[KEYCLOAK-7264] Add documentation for the new RoleMappingsProvider SPI
This commit is contained in:
parent
538cbc433f
commit
b1e487ec39
6 changed files with 139 additions and 0 deletions
|
@ -12,3 +12,16 @@ of extensions to access secrets from custom vaults.
|
|||
== Messages in theme resources
|
||||
|
||||
Message bundles in theme resources enables internationalization of custom providers such as authenticators. They are also shared between all theme types, making it possible to for example share messages between the login and account console. Thanks to https://github.com/micedre[micedre].
|
||||
|
||||
== RoleMappingsProvider SPI for the SAML adapters
|
||||
|
||||
We have added a new SPI that allows for the configuration of custom role mappers that are used by the SAML adapters to map
|
||||
the roles extracted from the SAML assertion into roles that exist in the SP application environment. This is particularly useful
|
||||
when the adapters need to communicate with third party IDPs and the roles set by the IDP in the assertion do not correspond to
|
||||
the roles that were defined for the SP application. The provider to be used can configured in the `keycloak-saml.xml`
|
||||
file or in the `keycloak-saml` subsystem. An implementation that performs the role mappings based on the contents of a properties
|
||||
file was also provided.
|
||||
|
||||
Notice that when {project_name} acts as the IDP we can use the built-in role mappers to perform any necessary mappings
|
||||
before setting the roles into the assertion, so this SPI will probably be redundant in this case. The `RoleMappingsProvider`
|
||||
SPI was designed for situations when the IDP offer no way to map roles before adding them to the assertion.
|
||||
|
|
|
@ -70,6 +70,7 @@ include::topics/saml/java/general-config/sp-keys/keystore_element.adoc[]
|
|||
include::topics/saml/java/general-config/sp-keys/key_pems.adoc[]
|
||||
include::topics/saml/java/general-config/sp_principalname_mapping_element.adoc[]
|
||||
include::topics/saml/java/general-config/roleidentifiers_element.adoc[]
|
||||
include::topics/saml/java/general-config/sp_role_mappings_provider_element.adoc[]
|
||||
include::topics/saml/java/general-config/idp_element.adoc[]
|
||||
include::topics/saml/java/general-config/idp_allowedclockskew_subelement.adoc[]
|
||||
include::topics/saml/java/general-config/idp_singlesignonservice_subelement.adoc[]
|
||||
|
|
|
@ -30,6 +30,9 @@ This is what one might look like:
|
|||
<RoleIdentifiers>
|
||||
<Attribute name="Role"/>
|
||||
</RoleIdentifiers>
|
||||
<RoleMappingsProvider id="properties-based-role-mapper">
|
||||
<Property name="properties.resource.location" value="/WEB-INF/role-mappings.properties"/>
|
||||
</RoleMappingsProvider>
|
||||
<IDP entityID="idp"
|
||||
signaturesRequired="true">
|
||||
<SingleSignOnService requestBinding="POST"
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
|
||||
===== RoleMappingsProvider Element
|
||||
|
||||
The `RoleMappingsProvider` is an optional element that allows for the specification of the id and configuration of the
|
||||
`org.keycloak.adapters.saml.RoleMappingsProvider` SPI implementation that is to be used by the SAML adapter.
|
||||
|
||||
When {project_name} is used as the IDP, it is possible to use the built in role mappers to map any roles before adding them to the
|
||||
SAML assertion. However, the SAML adapters can be used to send SAML requests to third party IDPs and in this case it might be
|
||||
necessary to map the roles extracted from the assertion into a different set of roles as required by the SP. The
|
||||
`RoleMappingsProvider` SPI allows for the configuration of pluggable role mappers that can be used to perform the necessary
|
||||
mappings.
|
||||
|
||||
The configuration of the provider looks as follows:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
...
|
||||
<RoleIdentifiers>
|
||||
...
|
||||
</RoleIdentifiers>
|
||||
<RoleMappingsProvider id="properties-based-role-mapper">
|
||||
<Property name="properties.resource.location" value="/WEB-INF/role-mappings.properties"/>
|
||||
</RoleMappingsProvider>
|
||||
<IDP>
|
||||
...
|
||||
</IDP>
|
||||
|
||||
----
|
||||
The `id` attribute identifies which of the installed providers is to be used. The `Property` sub-element can be used multiple times
|
||||
to specify configuration properties for the provider.
|
||||
|
||||
====== Properties Based Role Mappings Provider
|
||||
|
||||
{project_name} includes a `RoleMappingsProvider` implementation that performs the role mappings using a `properties` file. This
|
||||
provider is identified by the id `properties-based-role-mapper` and is implemented by the `org.keycloak.adapters.saml.PropertiesBasedRoleMapper`
|
||||
class.
|
||||
|
||||
This provider relies on two configuration properties that can be used to specify the location of the `properties` file
|
||||
that will be used. First, it checks if the `properties.file.location` property has been specified, using the configured
|
||||
value to locate the `properties` file in the filesystem. If the configured file is not located, the provider throws a
|
||||
`RuntimeException`. The following snippet shows an example of provider using the `properties.file.configuration`
|
||||
option to load the `roles.properties` file from the `/opt/mappers/` directory in the filesystem:
|
||||
|
||||
[source,xml,subs="attributes+"]
|
||||
----
|
||||
<RoleMappingsProvider id="properties-based-role-mapper">
|
||||
<Property name="properties.file.location" value="/opt/mappers/roles.properties"/>
|
||||
</RoleMappingsProvider>
|
||||
----
|
||||
|
||||
If the `properties.file.location` configuration has not been set, the provider checks the `properties.resource.location`
|
||||
property, using the configured value to load the `properties` file from the `WAR` resource. If this configuration property is
|
||||
also not present, the provider attempts to load the file from `/WEB-INF/role-mappings.properties` by default. Failure to load the file
|
||||
from the resource will result in the provider throwing a `RuntimeException`. The following snippet shows an example of provider
|
||||
using the `properties.resource.location` to load the `roles.properties` file from the application's `/WEB-INF/conf/` directory:
|
||||
|
||||
[source,xml,subs="attributes+"]
|
||||
----
|
||||
<RoleMappingsProvider id="properties-based-role-mapper">
|
||||
<Property name="properties.resource.location" value="/WEB-INF/conf/roles.properties"/>
|
||||
</RoleMappingsProvider>
|
||||
----
|
||||
|
||||
The `properties` file can contain both roles and principals as keys, and a list of zero or more roles separated by comma
|
||||
as values. When invoked, the implementation iterates through the set of roles that were extracted from the assertion and checks,
|
||||
for each role, if a mapping exists. If the role maps to an empty role, it is discarded. If it maps to a set of one ore more
|
||||
different roles, then these roles are set in the result set. If no mapping is found for the role then it is included as is
|
||||
in the result set.
|
||||
|
||||
Once the roles have been processed, the implementation checks if the principal extracted from the assertion contains an entry
|
||||
`properties` file. If a mapping for the principal exists, any roles listed as value are added to the result set. This
|
||||
allows the assignment of extra roles to a principal.
|
||||
|
||||
As an example, let's assume the provider has been configured with the following properties file:
|
||||
[source]
|
||||
----
|
||||
roleA=roleX,roleY
|
||||
roleB=
|
||||
|
||||
kc_user=roleZ
|
||||
|
||||
----
|
||||
|
||||
If the principal `kc_user` is extracted from the assertion with roles `roleA`, `roleB` and `roleC`, the final set of roles
|
||||
assigned to the principal will be `roleC`, `roleX`, `roleY` and `roleZ` because `roleA` is being mapped into both `roleX`
|
||||
and `roleY`, `roleB` was mapped into an empty role - thus being discarded, `roleC` is used as is and finally an additional role
|
||||
was added to the `kc_user` principal (`roleZ`).
|
||||
|
||||
====== Adding Your Own Role Mappings Provider
|
||||
|
||||
To add a custom role mappings provider one simply needs to implement the `org.keycloak.adapters.saml.RoleMappingsProvider` SPI.
|
||||
For more details see the `SAML Role Mappings SPI` section in link:{developerguide_link}[{developerguide_name}].
|
|
@ -14,6 +14,7 @@ include::topics/extensions.adoc[]
|
|||
include::topics/auth-spi.adoc[]
|
||||
include::topics/action-token-spi.adoc[]
|
||||
include::topics/events.adoc[]
|
||||
include::topics/saml-role-mappings-spi.adoc[]
|
||||
endif::[]
|
||||
include::topics/user-storage.adoc[]
|
||||
include::topics/user-storage/provider-interfaces.adoc[]
|
||||
|
|
29
server_development/topics/saml-role-mappings-spi.adoc
Normal file
29
server_development/topics/saml-role-mappings-spi.adoc
Normal file
|
@ -0,0 +1,29 @@
|
|||
[[_saml_role_mappings_spi]]
|
||||
== SAML Role Mappings SPI
|
||||
|
||||
{project_name} defines a SPI for mapping SAML roles into roles that exist in the SP environment. The roles returned by
|
||||
a third-party IDP might not always correspond to the roles that were defined for the SP application so there is a need for a
|
||||
mechanism that allows mapping the SAML roles into different roles. It is used by the SAML adapter after it extracts the roles
|
||||
from the SAML assertion to set up the container's security context.
|
||||
|
||||
The `org.keycloak.adapters.saml.RoleMappingsProvider` SPI doesn't impose any restrictions on the mappings that can be performed.
|
||||
Implementations can not only map roles into other roles but also add or remove roles (and thus augment or reduce the set of
|
||||
roles assigned to the SAML principal) depending on the use case.
|
||||
|
||||
For details about the configuration of the role mappings provider for the SAML adapter as well as a description of the default
|
||||
implementations available see the link:{adapterguide_link}[{adapterguide_name}].
|
||||
|
||||
=== Implementing a Custom Role Mappings Provider
|
||||
|
||||
To implement a custom role mappings provider one first needs to implement the `org.keycloak.adapters.saml.RoleMappingsProvider`
|
||||
interface. Then, a `META-INF/services/org.keycloak.adapters.saml.RoleMappingsProvider` file containing the fully qualified name
|
||||
of the custom implementation must be added to the archive that also contains the implementation class. This archive can be:
|
||||
|
||||
* The SP application WAR file where the provider class is included in WEB-INF/classes;
|
||||
* A custom JAR file which will be added into WEB-INF/lib of the SP application WAR;
|
||||
* (WildFly/JBoss EAP only) A custom JAR file configured as a `jboss module` and referenced in `jboss-deployment-structure.xml`
|
||||
of the SP application WAR.
|
||||
|
||||
When the SP application is deployed, the role mappings provider that will be used is selected by the id that was set in
|
||||
`keycloak-saml.xml` or in the `keycloak-saml` subsystem. So to enable your custom provider simply make sure that its id is
|
||||
properly set in the adapter configuration.
|
Loading…
Reference in a new issue