Custom User Storage SPI with groups and roles


I need to integrate an external system to federate users into Keycloak. That all works fine for the authentication part.
But I have problems integrating roles and groups stored in the external systems. I tried to due it by implementing getGroupsInternal() and getRoleMappingsInternal() on the UserModel. The problem is, that they don’t get propagated to the access token when doing OIDC with Keycloak. The roles and groups claims are part of the token, but the roles and groups of the external system are not part of the values in the access token.

Is it possible at all to propagate roles and groups with a user storage SPI or is the idea to manage the roles and groups in Keycloak directly? If it is possible, can anybody point me to an example how it should be done or knows why my roles and groups are not part of the access token?

Thanks a lot for your help!

I´m a bit late for your question but I leave it here …

My custom UserAdapter implements getRoleMappingsInternal and getGroupsInternal - both return a Set of my own GroupModel and RoleModel.
The GroupModelAdapter works (I can see present roles in the user manager) - the RoleModelAdapter does not so far - the roles are returned but not displayed and/or mapped.

AFAIK only roles are mapped to the JWT token by default - so my implementation in this way does not work.
To get the job done I wrote my own TokenMapper to filter my groups (by regex), transform the names and to map them to the token as (misinterpreted) roles.

It´s not conform to default keycloak-rolemapping (so far) - but according to Microprofile JWT (which uses a different groups / role-mapping in the token).

I couldn´t help myself any better since the documentation is a bit thin …

If anybody has a solution for correct group / roles mapping of a custom UserProvider in keycloak, please let me know

Note to myself: I´m stupid

In my UserAdapter in getRoleMappingsInternal I processed the Role List but always returned an EMPTY_LIST and not the result.

Oh wonder: it works out of the box with correct return statement!

┑( ̄Д  ̄)┍