6

I've followed the guide at [1] to map a single user attribute. However, I need to map all attributes to an array, so that every attribute for a particular User shows up in an attribute array of the access token (Or better, restrict attributes to a certain group of attributes, but I guess user attributes are only a flat key/value map).

I tried out setting a wildcard * in the User Attribute field of the client mapper. But no matter what I do, I can ony set one attribute at a time given an actual attribute key of a user's attribute map.

[1] Keycloak retrieve custom attributes to KeycloakPrincipal

benjist
  • 2,740
  • 3
  • 31
  • 58

4 Answers4

14

I was in trouble with the same problem.

I have tried the following:

  1. Added a key "department" with a single value for example "finance". Adding a second key "department" with another value "development" overwrites the initial entry.
  2. I also have tried to put something like a list into the value column, such as "development, finance" or "development; finance" but this is treated as a single value too.

If you use "development##finance" in admin console, the user will have "department" attribute with 2 values "development" and "finance".

The "##" seem to be the delimiter to use.

So, if you mark "multivalued" switch in your protocolMapper for "department" attribute, the accessToken will contain list with 2 values "development" and "finance".

"department": [ "development", "finance" ]

This worked for me.

KeyCloak version 11.0.2

Fabio
  • 141
  • 1
  • 3
3

I'm not 100% sure what you're looking for here, but I know this is the first result that came up when I googled what I was looking for, so I'll just post that answer here.

Say you want a multi-valued user attribute set in a JWT in keycloak, but your attributes aren't the same name. E.g. you have something like the following key value set for a user:

Room : Bedrooom
Floor: Tile
Paint: White

Next, you want these values within the JWT

{
  "exp": xxxxxxxxxx,
  "iat": xxxxxxxxxx,
  "jti": "xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
  "iss": "xxxxxxxxx",
  ...
  "Room_Info":{
    Room : Bedrooom
    Floor: Tile
    Paint: White
   }
  ...
}

When using you're mapper in keycloak, preappend your Token Claim Name (Room_Info) with a dot. keycloak_user_attributes

That should do it.

Woody
  • 125
  • 8
0

You can write your own Keycloak extension. One solution would be to write custom Authenticator where you can: filter user attributes -> join attributes values -> write resulted JSON array as user session note.

Then add Client Mapper which maps this session note into a single claim.

Pawel.S.
  • 216
  • 1
  • 5
0

Actually there is an easier solution (I successfully tested it with Keycloak version >= 21 - but might also work for previous versions).

You can just simply add multiple attributes with the same key:

User Attributes

A multivalued client scope mapper (See Woodys answer) will then combine all of the values into a single array within the token:

Token

Please note: When you are using the Admin API to update user attributes you have to send the attribute as an array in order not to override any existing values:

{
   "attributes":{
      "data-disclosure":[
         "{\"version\":1,\"grantedAt\":\"2023-07-21T13:47:41.357Z\"}",
         "{\"version\":2,\"grantedAt\":\"2023-07-21T13:47:41.357Z\"}"
      ]
   }
}