Keycloak harcoded claim for each user

Viewed 1474

I use the micro-services architecture. Each service uses bearer access type. The users get token by public service. Each service is business application with own privelegies. Rabbit mq is used as interprocess communication. Keycloak transfers user roles for each service by JWT. But I would like to transfer user privelegies in the user's token.

Like this :

priveleges:[
 {resource: subjects,
  roles:[ADMIN,OPER,COMPLAINCE],
  categories:[
    read:[1,2,3,4,5],
    write:[3,4,5],
    delete:[3,4,5] 
  ],
  notes:[
    read:[1,2,3,4,5],
    write:[3,4,5],
    delete:[3,4,5]  
  ],
  subject:[
    read:true,
    write:true,
    delete:false
  ],
  addresses:[
    read:true,
    write:true,
    delete:false
  ]
 },


 {resource: cards,
  roles:[ADMIN,OPER,COMPLAINCE],
  card:[
    read:true,
    write:true,
    delete:false
  ],
  fin-operation:[1,2,3,4,5],
  non-fin-operation:[1,2,3,4]
 }
]

I have two questions:

  1. Can I set different privileges for each user in keycloak? I know it is possible to use a ProtocolMapper with a hardcoded mapper type in Keycloak. And in this case it will be one for all users but I need to have privileges claim for each user.

  2. Is it correct to pass privileges in a token, so that later they can be processed on the backend and frontend?

Additional information: But if I try to add string value more 255 chars, I catch the error because it is constraint of it field. I have the error in logs jboss : ERROR: value too long for type character varying(255)

I try to add this claim:

{ "priveleges":[ { "resource":"subjects", "roles":[ "ADMIN", "OPER", "COMPLAINCE" ], "categories":[ { "read":[ 1, 2, 3, 8, 5 ] }, { "write":[ 3, 9, 5 ] }, { "delete":[ 3, 6, 5 ] } ], "notes":[ { "read":[ 1, 2, 3, 7, 5 ] }, { "write":[ 3, 4, 5 ] }, { "delete":[ 3, 4, 5 ] } ] }, { "resource":"cards", "roles":[ "ADMIN", "OPER", "COMPLAINCE" ], "fin-operation":[ 1, 2, 3, 4, 5 ], "non-fin-operation":[ 1, 2, 3, 4 ] } ] }

enter image description here

1 Answers

Can I set different privileges for each user in keycloak? I know it is possible to use a ProtocolMapper with a hardcoded mapper type in Keycloak. And in this case it will be one for all users but I need to have privelegies claim for each user.

If I correctly understand what you mean by "privileges", you can implement it at least in the following two ways: 1) Create and assign Realm roles to the users, accordingly, and create a custom user attribute on each of your users. Alternatively, you can use Keycloak Authorization features to deal with that, but it will require some work.

Is it correct to pass privileges in a token, so that later they can be processed on the backend and frontend?

Yes, it is common to use Keycloak for authentication and a backend to perform the authorization part based on the roles injected on the token requested on some user's behalf.

Let me provide you with an illustrative example. First create the Realm Roles by going to:

  • Your Realm;
  • Select Roles;
  • Add Role;
  • Now create a separate role for ADMIN, OPER and COMPLAINCE, for instance;
  • Save those roles;

enter image description here

Now let us assign the Realm Roles to the user and create an User Attribute by going to:

  • Your Realm;

  • Users;

  • Click on a user;

  • Switch the tab to Role Mappings;

  • Select the Realm Roles that you want to assign to the user, and click on Add selected; enter image description here

  • Now go to Attributes;

  • Add the rest of the claims into the user. For example, Key = "priveleges" and value = {"resource": "subjects","categories": [{"read": [1,2,3,8,5]},{"write": [3,9,5]},{"delete": [3,6,5]}],"notes": [{"read": [1,2,3,7,5]},{"write": [3,4,5]},{"delete": [3,4,5]}]}.

enter image description here

To finalize, you need to created a Mapper to map the newly create user attribute into the token. For that, go to:

  • Your Realm;
  • Clients;
  • Select your client;
  • Mappers;
  • Create;
  • Fill up the fields, namely
    • Name : "priveleges"
    • As Mapper Type select "User Attribute";
    • User Attribute : priveleges;
    • Token Claim Name : priveleges;
    • Claim JSON Type : JSON;
    • Fill up the rest accordingly.
    • Click Save.

enter image description here

Now request a token to your client on the user's behalf. The decoded token will look like the following:

 "iat": ......,
  "jti": "......",
  "iss":  "......",
  "aud":  "......",
  "sub":  "......",
  "typ":  "......",
  "azp":  "......",
  "session_state":  "......",
  "acr": "1",
  "allowed-origins": [
    "http://localhost:8080"
  ],
  "realm_access": {
    "roles": [
      "COMPLAINCE",
      "offline_access",
      "uma_authorization",
      "ADMIN",
      "OPER",
      "app-user"
    ]
  },
  "resource_access": {
    "springboot-microservice": {
      "roles": [
        "user"
      ]
    },
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  },
  "scope": "profile email",
  "email_verified": true,
  "priveleges": {
      "resource": "subjects",
      "categories": [
        {
          "read": [
            1,
            2,
            3,
            8,
            5
          ]
        },
        {
          "write": [
            3,
            9,
            5
          ]
        },
        {
          "delete": [
            3,
            6,
            5
          ]
        }
      ],
      "notes": [
        {
          "read": [
            1,
            2,
            3,
            7,
            5
          ]
        },
        {
          "write": [
            3,
            4,
            5
          ]
        },
        {
          "delete": [
            3,
            4,
            5
          ]
        }
      ]
   },
  "name": "e 1",
  "preferred_username": "employee1",
  "given_name": "e",
  "family_name": "1",
}

The roles are under the claim:

 "realm_access": {
    "roles": [
      "COMPLAINCE",
      "offline_access",
      "uma_authorization",
      "ADMIN",
      "OPER",
      "app-user"
    ]

However, if you want the Realm Roles also under the priveleges claim, you need to add them into the user attribute claim that we have previously created.

Bear in mind, however, that there is a limit on how many characters one can save per user attribute (i.e., 255 characters). So you might have to split your claim into multiple claims (i.e., user attributes).

Related