keycloak

KeyCloak - How to add Role's attribute into a user JWT (Access Token)?


I’m trying to figure out how to add role attributes into a JWT token (Access Token).

I created a new Role named “Manager” with an attribute named “Actions”.

Role's attribute pic

Then I defined a new Client Scope named “Actions” with a mapper named “Actions” that map a user attribute named “actions” into the token.

actions_client_scope

actions_mapper

Then I took a client we have named “API” and added this client scoper as a default one.

API client scopes

Finally, I created a new user and gave him the Manager role.

dummy user roles

Now, since this user is for the “Manager” role, and the role was defined with an attribute named “actions” I expected that the user will get those attributes as well and therefore when getting an access token from the API client those will appear in the JWT(AT).

but it doesn’t work.

If I do the same things but with a group (creating a group with attributes and giving the user this group) everything works fine.

Is this by design or am I doing something wrong?

i tried to create both user Attribute mapper and cliet role mappers with no luck.


Solution

  • Is this by design or am I doing something wrong?

    Your rational was good. Unfortunately, the problem is that Keycloak does not consider the role attributes to be user attributes. Consequently, your mapper of "user attribute" type has no effect. Hence, nothing is added to the JWT token.

    Currently, there is an open feature in the Keycloak GitHub repo to handle this situation. Have a look at [KEYCLOAK-17418] Should role attributes be made available as user attributes.

    As a "workaround" there are answers (e.g., here and here) on stack overflow that implements this Mapper through the use of Keycloak Script Mapper feature.

    Another, better approach IMO, would be for you to create the Mapper by extending the Keycloak code via its Service Provider Interfaces mechanism. Here is an example of this approach. You can use the code displayed on aforementioned SO answers that use the script Mapper to infer the java code from it.