This project provides a Keycloak broker mapper that maps a multivalued OIDC claim (e.g.: groups) or SAML attribute (e.g.: groupMembership) into one or more realm and/or client role assignments based on regular expressions.
Copy keycloak-regex-mapper-«version».jar
to ${KEYCLOAK_HOME}/providers
.
The Advanced Claim to Role (OIDC) and Advanced Attribute to Role (SAML) mappers included with Keycloak provide a mechanism to map specific claim/attribute values to a specific target realm or client. This can be tedious to configure if there are many target roles that should be mapped.
The purpose of the Regex Realm and Client Role Importer mappers (one for OIDC, one for SAML)
included in this project is to provide a mechanism to map many entries in an OIDC claim
( e.g., groups
) or SAML attribute (e.g.: groupMembership
) to target roles using a single
configured mapper.
The mechanism relies on two principles:
- that the claim / attribute provider uses clientId and realmName values when naming things... in other words, the mapping exists on the claim/attribute provider
- assigning an attribute to each realm and claim role to be managed by the mapper
Suppose that the claim provider has a group structure as follows:
/IdentityBrokers
/idb1 # this is the realm
/Roles # these are the realm roles
SupportAnalyst # A
member=alice
member=bob
/ServiceProviders # these are the clients
/sp1 # B
/Roles # these are the client roles for sp1
Impersonator # C
member=alice
/sp2 # D
/Roles # these are the client roles for sp2
OtherRole # E
member=bob
Then, when Alice logs in to / through idb1, the groups
claim would contain:
IdentityBroker/idb1/Roles/SupportAnalysts
IdentityBroker/idb1/ServiceProviders/sp1/Roles/Impersonator
Whereas Bob's would contain:
IdentityBroker/idb1/Roles/SupportAnalysts
IdentityBroker/idb1/ServiceProviders/sp2/Roles/OtherRole
At the identity broker, realm and client roles would be configured as follows:
Roles # these are the realm roles
SupportAnalyst # matches A above
Clients
sp1 # matches B above
Roles # these are the client roles for sp1
Impersonator # matches C above
attribute:
key="automatically mapped"
value="true"
sp2 # matches D above
Roles # these are the client roles for sp2
OtherRole # matches E above
attribute:
key="automatically mapped"
value="true"
And the Regex Realm and Client Role Importer mapper would be configured as follows:
configuration key | value |
---|---|
type | Regex Realm and Client Role Importer |
name | groups to realm and client roles |
sync mode override | force |
OIDC claim name | groups |
client roles attribute name | automatically mapped |
client roles regular expression | /IdentityBrokers/idb1/ServiceProviders/(?<client>.*)/Roles/(?<role>.*) |
realm roles attribute name | automatically mapped |
realm roles regular expression | /IdentityBrokers/idb1/Roles/(?<role>.*) |
The purpose of the the client roles attribute name
and the realm roles attribute name
is to flag
for the mapper which client and realm roles to assign / un-assign. Otherwise, every role not
matching the regular expressions would be un-assigned, including those that might have been locally
assigned by an administrator.
Take note of the named groupings (e.g.: (?<client>.*)
in the regular expressions:
- the
client roles regular expression
needs two:client
androle
. - The
realm roles regular expression
only needs one:role
.
Suppose the attribute provider draws group membership from an LDAP server structured as follows:
dc=example,dc=com
ou=IdentityBrokers
ou=idb1
ou=Roles # realm roles
cn=SystemAnalyst
member=alice
member=bob
ou=ServiceProviders
ou=sp1
ou=Roles # client roles for sp1
cn=Impersonator
member=alice
ou=sp2
ou=Roles # client roles for sp2
cn=OtherRole
member=bob
For Alice, groupMembership would contain:
cn=SystemAnalyst,ou=Roles,ou=idb1,ou=IdentityBrokers,dc=example,dc=com
cn=Impersonator,ou=Roles,ou=sp1,ou=ServiceProviders,ou=idb1,ou=IdentityBrokers,dc=example,dc=com
For Bob, groupMembership would contain:
cn=SystemAnalyst,ou=Roles,ou=idb1,ou=IdentityBrokers,dc=example,dc=com
cn=OtherRole,ou=Roles,ou=sp2,ou=ServiceProviders,ou=idb1,ou=IdentityBrokers,dc=example,dc=com
Assuming the same realm and client role configuration as above (in the OIDC example), then the Regex Realm and Client Role Importer mapper would be configured as follows:
configuration key | value |
---|---|
type | Regex Realm and Client Role Importer |
name | groups to realm and client roles |
sync mode override | force |
SAML attribute name | groupMembership |
client roles attribute name | automatically mapped |
client roles regular expression | cn=(^<role>.*),ou=Roles,ou=(^<client>.*),ou=ServiceProviders,ou=idb1,ou=IdentityBrokers,dc=example,dc=com |
realm roles attribute name | automatically mapped |
realm roles regular expression | cn=(^<role>.*),ou=Roles,ou=idb1,ou=IdentityBrokers,dc=example,dc=com |
This project follows the module/bundle approach to packaging keycloak extensions:
-
module
builds the jar that contains the keycloak extensions -
bundle
builds the ear that contains the jar frommodule
and any jars that are not designated asprovided
dependencies
This project uses:
-
checkstyle to achieve compliance with the Google Java Style Guide. Please add the checkstyle plugin to your IDE.
-
SonarLint to improve code quality and code security. Please add the SonarLint plugin to your IDE.
Copyright 2021 Luca Filipozzi. Some rights reserved. See LICENSE.