Skip to content

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

License

Notifications You must be signed in to change notification settings

LucaFilipozzi/keycloak-regex-mapper

license latest tag latest release

build analyze dependabot

languages alerts code quality

lines of code maintainability technical debt

keycloak-regex-mapper

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.

usage

deployment

Copy keycloak-regex-mapper-«version».ear to ${KEYCLOAK_HOME}/deployments.

configuration

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

OIDC Example

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 and role.
  • The realm roles regular expression only needs one: role.

SAML example

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

development

project structure

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 from module and any jars that are not designated as provided dependencies

coding conventions

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.

About

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

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Languages