We’ve finally analyzed our problems about the Saml attribute to role mapper. Basically, our configuration was wrong, but let me explain what we’ve done and what could be useful for other users:
- We’re brokering Keycloak master realm with our Okta authorization server
- We wanted to assign a single role based on the fact that the user was belonging to one of those groups in okta: GroupA, GroupB, GroupC, GroupD
- The information about the group, is passed in a SAML Attribute named “groups”
- To handle several groups we’ve configured 4 Attribute to role mappers. Every of those mappers controls if the “groups” attribute name is equal to one of the 4 groups defined in Okta. With this i mean that the first mapper controls the value “GroupA”, the second controls the value “GroupB” etc.
- Every attribute to role mapper assigns the same role, “Full Access”
This drove us to an unexpected situation where sometimes the role was assigned, sometimes not. The problem was present only when the brokering happened for users already present in the Master Realm.
We looked at the code, and we saw the method updateBrokeredUser in the AttributeToRoleMapper.java class. This method is called for every attribute to role mapper. And here comes the problem which i’ll explain with an example:
- User A is already present in the Master Realm
- User A is assigned in Okta to GroupA
- User A access Keycloak via Okta, and authenticates on Okta
- The SAML assertion coming from Okta, contains the correct attribute “groups”, valued with “GroupA”
- updateBrokerUser gets called for the Attribute To Role Mapper which handles the “GroupA” value. At this point, the role “Full Access” is assigned to the user
- updateBrokerUser gets called for all the remaining Attribute To Role Mappers. At this point, the role is removed from the user, since the SAML assertion doesn’t contain the values “GroupB”, “GroupC” and “GroupD”.
This situation is non deterministic since it depends on how the Attribute Mappers are retrieved from the db (the order).
At this point, what’s the best way to handle several possible values in one Attribute to Role Mapper? Something like: if the “groups” SAML Attribute is valued “GroupA, GroupB, GroupC” assign the role “Full Access”.
Or do we have to build a custom mapper?
PS: we’re using Keycloak 6.0.1 version