From 22a445d2c408396a458cf493f1bde8b9d763f0aa Mon Sep 17 00:00:00 2001 From: Luca Filipozzi Date: Mon, 23 Aug 2021 13:20:55 -0700 Subject: [PATCH] improve documentation --- README.md | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a404728..1311ffe 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ # keycloak-regex-mapper -This project provides a [keycloak][keycloak] broker mapper that maps a +This project provides a [Keycloak][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. @@ -29,7 +29,150 @@ Copy `keycloak-regex-mapper-«version».ear` to `${KEYCLOAK_HOME}/deployments`. ### configuration -TODO +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/(?.*)/Roles/(?.*)` | +| realm roles attribute name | `automatically mapped` | +| realm roles regular expression | `/IdentityBrokers/idb1/Roles/(?.*)` | + +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.: `(?.*)` 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=(^.*),ou=Roles,ou=(^.*),ou=ServiceProviders,ou=idb1,ou=IdentityBrokers,dc=example,dc=com` | +| realm roles attribute name | `automatically mapped` | +| realm roles regular expression | `cn=(^.*),ou=Roles,ou=idb1,ou=IdentityBrokers,dc=example,dc=com` | ## development @@ -39,8 +182,8 @@ 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 the jars for - any not-provided dependencies +* `bundle` builds the ear that contains the jar from `module` and any jars that are + not designated as `provided` dependencies ### coding conventions