3

i have a scenario where i want to restrict the user in keycloak

i have user

user can have access to multiple accounts in multiple accounts, use can be Admin or agent (reader)

user
|
|
|-------account-1
|            |
|            |-------admin
|-------account-2
|            |
|            |-------agent

How can we map this in Keycloak with Policy, Permission, and role?

any reference document any example really helpful

also based from : Resources, scopes, permissions and policies in keycloak

From the answer of Andy, i have created one resource Account and role admin & agent.

created same policies as in example.

i am looking forward to add scopes (auth scope) and roles to JWT token how to map that part so that API gateway or service can verify further.

chagan
  • 179
  • 4
  • 15
  • Did you have a look at https://www.keycloak.org/docs/latest/authorization_services/ – dreamcrash Mar 16 '21 at 17:32
  • @dreamcrash i have checked it RBAC and all but i not sure about creating resource and policy how it will. in my case i think Account will be resource. Roles will be Admin and Agent. i am stuk with policy and permission. – chagan Mar 17 '21 at 04:32
  • Hmm - I think further clarification is needed. Are you trying to implement some sort of [user impersonation](https://www.keycloak.org/docs/latest/server_admin/#impersonation)? – Andy Mar 17 '21 at 19:15
  • @Andy no i read document, what i am basically looking forward my application has two types of userroles `admin` and `agent`. users may have access to multiple accounts. in some account user might be `admin` or `agent` – chagan Mar 18 '21 at 03:54
  • based on your this answer : https://stackoverflow.com/a/58906945/12556258....i have created client roles, resource and eveything. now i want basic auth scope and roles into JWT so restrict user at API gateway level. Please suggest better way also if you have any suggestions. – chagan Mar 18 '21 at 03:56
  • Ah I see. I'll get back to you tomorrow (if you you haven't received an answer by then). – Andy Mar 18 '21 at 05:50
  • @Andy i don't think anyone will join the party. – chagan Mar 18 '21 at 14:12
  • Hey, you never know but no worries :) I'm at work right now but I promise I will get back to you. What is your timezone? Mines EST - we can always coordinate to chat as well. – Andy Mar 18 '21 at 14:27
  • i am in IST timezone, if you can please share the point of contact or LinkedIn profile we can discuss in chat also there. – chagan Mar 18 '21 at 16:06
  • We can use this [chat room](https://chat.stackoverflow.com/rooms/230103/room-for-andy-and-chagan) I'll periodically check on it an reply. Might not be as quick since it's late here. – Andy Mar 18 '21 at 23:47

1 Answers1

14

@changa, I've rewritten my answer based on our discussion. Hope this helps!

Let me first clarify some key areas before I answer. My main focus on the answer that you've linked was really on how to play around the Evaluate tool and I didn't really dive too deeply into some of the concepts - so let's do that :)

In Keycloak, you'll encounter Client and Authorization Scopes. For a formal definition of these terms please check out the Core Concepts and Terms in the Server Administration Guide, but simply put:

Client Scopes are scopes which are granted to clients when they are requested via the scope parameter (once the resource owner permits it). Note that there's also the concept of Default Client Scope but I've chosen to keep things simple. Furthermore, you can leverage protocol and role scope mappers to tailor what claims and assertions are present in the access token.

Authorization Scopes on the other hand are granted to clients after successful evaluation of the policies against a protected resource. These scopes are not granted to clients based on user consent.

The key differences between the two is really when and how a client obtains these scopes. To help you visualize all of this, here's a scenario:

  1. A renowned martial artist called Bob authenticates via Keycloak

  2. Bob get presented with a consent screen where he is asked to share his name, his fighting style and his age.

  3. Bob chooses to give access to his name and fighting style but he declines to share his age.

  4. When we inspect the token now, we would see the following (completely made up) entries for the scope attribute of the access token: name and fighting_style.

  5. Additionally, let's assume that we've set up a couple of protocol mappers (e.g. User Attribute Mapper Type - there are a ton) to display the values for full name and fighting style via the following token claims: fighter_name and martial_arts when the two Client Scopes above are present in the access token. In addition to two previously mentioned scopes, we would also see something like fighter_name: Robert Richards and martial_arts: Freestyle Karate when examining the access token.

    • Side Note: Given the length of this answer, I've decided to skip this topic but please check out this awesome video at around the 7 minute mark along with the associated GitHub Project for more information. The README is pretty good.
  6. Additionally, let's assume that Bob is mapped to a realm role called Contestant and a client role of Fighter and we did place any restrictions in Keycloak when it comes to sharing this info. So in addition to all the things mentioned above, we would see that information inside the token as well.

    • Needless to say, this is an oversimplification on my part as I'm simply setting up the stage for demo. purposes and there's much more information inside the access token.
  7. Bob doesn't like how the tournament bracket is laid out as he's eager to fight the world champ as soon as possible, so he attempts to change his placement by sending a request against tournament/tekken6/bracket/{id}. This resource is associated with the scope bracket:modify. Additionally, there is a permission which associates the resource in question with a role based policy named Referee Role Required. If Bob were a Referee then he would be granted the bracket:modify scope but since he isn't, then he is denied that scope.

    • I've barely touched the surface when it comes to the inner workings of the Authorization process in Keycloak. For more information, check out this practical guide. You can do some pretty cool stuff with UMA.

Ok, so that's enough theory. Let's set up our environment to demo all of this. I'm using the following:

  • A realm called demo
  • A client called my-demo-client
  • A client scope called client_roles
  • 2 users - paul and law
  • Two realms level roles - Admin and Reader
  • Two client level roles - demo-admin and demo-reader

Please note that I will using Keycloak 12.0.4 and I will skip almost all the basic setup instructions. I will only share the relevant bits. If you're not sure how to set this all up, please check out the Getting Started Guide or this answer. The answer contains steps for version 8 but the differences are very minor as far as I could tell.

Associating Users And Roles

In order to associate paul with the Admin, Reader, bank-admin and bank-reader roles, please do the following:

  • Click on Users > View all users > Click on the ID value for paul > Click on Role Mappings > Under Realm Roles move Admin and Reader under Assigned Roles > Select my-demo-client under the Client Roles select box and move demo-admin and demo-reader under Assigned Roles like so

enter image description here

  • As for law we'll just associate him with Reader and bank-reader.

Associating a client scope with a client

Create a Client Scope by:

  • Clicking on the Client Scopes link on the left > Click on Create > Enter custom-client-scope for the Name field and Hit Save. It should look like this

enter image description here

  • Click on Clients on the left > Select the my-demo-client > Click on the Client Scopes tab at the top > and let's just move it to Assigned Default Client Scopes for convenience.

Inspecting the Access Token

We can easily generate an access token for our setup via Keycloak to see what it looks like. In order to do so:

  • Click on Evaluate tab under Client Scopes.

  • Select paul as the user

  • Click on the blue Evaluate button

  • Click on Generated Access Token. While inspecting the token, look for:

    • resource_access to see client level roles associated with paul
    • realm_access to see paul's realm level roles
    • scope to see the Client Scope that we created called custom-client-scope enter image description here enter image description here
  • If you generate a token for law, you would see less roles when compared to paul.

Obtaining a Scope After Policy Evaluation

Continuing with our setup:

  • I've created an account/{id} resource with two Authorization Scopes called account:read and account:modify like so

enter image description here

  • Additionally, I've created two role based policies called Only Reader Role Policy and Only Admin Role Policy where the former requires the Reader realm role while the latter requires the Admin realm role. Here's an example for reference.

enter image description here

  • Note that you can further enhance that policy at the client level if you wish but to keep things simple, I chose not to do so.

  • Furthermore, I've created two scoped based permissions called Read Account Scope Permission and Modify Account Scope Permission.

  • The Read Account Scope Permission will grant the account:read Authorization Scope if the user is either an Admin or a Reader. One key thing to notice here is the the Decision Strategy has to be set to Affirmative in order to achieve this behavior.

enter image description here

  • Modify Account Permission on the other hand grants the account:modify Authorization Scope to users with the Admin role.

enter image description here

  • Now, if you choose the evaluate the user paul (remember he is both Admin and Reader) against the Account Resource, he will be granted both the account:read and account:modify Authorization Scopes. Let's see if this true. Here's our Evaluate screen and notice that I did not associate any roles with paul since this was already done via the Users > Role Mappings tab

enter image description here

  • And here are the results of that evaluation as predicted

enter image description here

  • Here is the evaluation result for law. Since he's not an Admin he'll be denied the account:modify scope but he'll be granted the account:read scope.

enter image description here

  • And finally, we can further confirm this by click on Show Authorization Data which shows the permissions inside the access token for law

enter image description here

Hopefully this helps you see where each piece of the puzzle fits in your architecture. Cheers!

Andy
  • 5,900
  • 2
  • 20
  • 29
  • @chagan I hope this helps. I feel like I'm forgetting something....hmmm... – Andy Mar 18 '21 at 23:47
  • Thanks a lot, Andy. for taking out time and writing the answer will all minor details. in your answer https://stackoverflow.com/questions/42186537/resources-scopes-permissions-and-policies-in-keycloak/58906945#58906945....you mentioned about RBAC and scope permission. – chagan Mar 19 '21 at 04:23
  • 1
    i have implemented some scope base policies along with resources and auth scope (as per answer example it is `account:view`) now how can i add this auth scope to `account:view` to JWT token that is what i am stuck at. – chagan Mar 19 '21 at 04:25
  • 1
    Just for ref if in facing --data-urlencode error : `curl -X POST \ https://keycloak.example.tk/auth/realms//protocol/openid-connect/token \ -H 'cache-control: no-cache' \ -H 'content-type: application/x-www-form-urlencoded' \ -d 'client_id=app-client&grant_type=password&scope=openid&username=&password=&client_secret='` – Harsh Manvar Mar 19 '21 at 05:22
  • 1
    @HarshManvar oh, I didn't realize - my mistake sorry. I took the curl straight from POSTMAN. I'll update the answer in a bit. Thank you for the feedback :) – Andy Mar 19 '21 at 12:22
  • @changan ah, scopes. I knew I forgot something. Give me a few hours, sorry about that, – Andy Mar 19 '21 at 12:25
  • No worries @Andy please take your time it's fine. also i have added some messages in chat room if you can please check that out also that would be really helpful. – chagan Mar 19 '21 at 12:28
  • https://chat.stackoverflow.com/rooms/230103/room-for-andy-and-chagan – chagan Mar 19 '21 at 12:28
  • this guy has explained question better way : https://stackoverflow.com/questions/62537162/set-scopes-for-access-token-returned-by-keycloak – chagan Mar 19 '21 at 12:29
  • 1
    @chagan I understand you issue no worries. We will definitely figure it out. I replied :) – Andy Mar 19 '21 at 12:49
  • Perfect no worries, please take your time. – chagan Mar 19 '21 at 12:54
  • Thanks a lot...Andy for all the help and everything for sharing the demo and clearing out all doubts. You saved my dayssssss...! – chagan Mar 20 '21 at 20:22
  • 1
    @chagan My pleasure! And thank you also for the feedback. I'm going to update my answer here soon and use this oppurtunity to clear/expand on some of the existing concepts! Check back in a couple of days :) – Andy Mar 21 '21 at 02:00