244 lines
No EOL
16 KiB
XML
Executable file
244 lines
No EOL
16 KiB
XML
Executable file
<chapter id="user_federation">
|
|
<title>User Federation SPI and LDAP/AD Integration</title>
|
|
<para>
|
|
Keycloak can federate external user databases. Out of the box we have support for LDAP and Active Directory.
|
|
Before you dive into this, you should understand how Keycloak does federation.
|
|
</para>
|
|
<para>
|
|
Keycloak performs federation a bit differently than other products/projects. The vision of Keycloak is that it
|
|
is an out of the box solution that should provide a core set of feature irregardless of the backend user storage you
|
|
want to use. Because of this requirement/vision, Keycloak has a set data model that all of its services use.
|
|
Most of the time when you want to federate an external user store, much of the metadata that would be needed to
|
|
provide this complete feature set does not exist in that external store. For example your LDAP server may only
|
|
provide password validation, but not support TOTP or user role mappings. The Keycloak User Federation SPI was
|
|
written to support these completely variable configurations.
|
|
</para>
|
|
<para>
|
|
The way user federation works is that Keycloak will import your federated users on demand to its local storage. How
|
|
much metadata that is imported depends on the underlying federation plugin and how that plugin is configured. Some
|
|
federation plugins may only import the username into Keycloak storage, others might import everything from name,
|
|
address, and phone number, to user role mappings. Some plugins might want to import credentials directly into
|
|
Keycloak storage and let Keycloak handle credential validation. Others might want to handle credential validation
|
|
themselves. The goal of the Federation SPI is to support all of these scenarios.
|
|
</para>
|
|
<section>
|
|
<title>LDAP and Active Directory Plugin</title>
|
|
<para>
|
|
Keycloak comes with a built-in LDAP/AD plugin. By default, it is set up only to import username, email, first and last name, but you are free
|
|
to configure <link linkend='ldap_mappers'>mappers</link> and add more attributes or delete default ones.
|
|
It supports password validation via LDAP/AD protocols and different user metadata synchronization modes. To configure
|
|
a federated LDAP store go to the admin console. Click on the <literal>Users</literal> menu option to get you
|
|
to the user management page. Then click on the <literal>Federation</literal> submenu option. When
|
|
you get to this page there is an "Add Provider" select box. You should see "ldap" within this list. Selecting
|
|
"ldap" will bring you to the ldap configuration page.
|
|
</para>
|
|
<section>
|
|
<title>Edit Mode</title>
|
|
<para>
|
|
Edit mode defines various synchronization options with your LDAP store depending on what privileges
|
|
you have.
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>READONLY</term>
|
|
<listitem>
|
|
<para>
|
|
Username, email, first and last name and other mapped attributes will be unchangeable. Keycloak will show an error
|
|
anytime anybody tries to update these fields. Also, password updates will not be supported.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>WRITABLE</term>
|
|
<listitem>
|
|
<para>
|
|
Username, email, first and last name, other mapped attributes and passwords can all be updated and will
|
|
be synchronized automatically with your LDAP store.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>UNSYNCED</term>
|
|
<listitem>
|
|
<para>
|
|
Any changes to username, email, first and last name, and passwords will be stored
|
|
in Keycloak local storage. It is up to you to figure out how to synchronize back to
|
|
LDAP.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
</section>
|
|
<section>
|
|
<title>Other config options</title>
|
|
<para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>Display Name</term>
|
|
<listitem>
|
|
<para>
|
|
Name used when this provider is referenced in the admin console
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Priority</term>
|
|
<listitem>
|
|
<para>
|
|
The priority of this provider when looking up users or for adding registrations.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Sync Registrations</term>
|
|
<listitem>
|
|
<para>
|
|
If a new user is added through a registration page or admin console, should the user
|
|
be eligible to be synchronized to this provider.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Allow Kerberos authentication</term>
|
|
<listitem>
|
|
<para>
|
|
Enable Kerberos/SPNEGO authentication in realm with users data provisioned from LDAP. More info in <link linkend="kerberos">Kerberos section</link>.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Other options</term>
|
|
<listitem>
|
|
<para>
|
|
The rest of the configuration options should be self explanatory. You can use tooltips in admin console
|
|
to see some more details about them.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
</section>
|
|
</section>
|
|
<section>
|
|
<title>Sync of LDAP users to Keycloak</title>
|
|
<para>
|
|
LDAP Federation Provider will automatically take care of synchronization (import) of needed LDAP users into Keycloak database.
|
|
For example once you first authenticate LDAP user <literal>john</literal> from Keycloak UI, LDAP Federation provider will
|
|
first import this LDAP user into Keycloak database and then authenticate against LDAP password.
|
|
</para>
|
|
<para>
|
|
Federation Provider imports just requested users by default, so if you click to <literal>View all users</literal>
|
|
in Keycloak admin console, you will see just those LDAP users, which were already authenticated/requested by Keycloak.
|
|
</para>
|
|
<para>If you want to sync all LDAP users into Keycloak database, you may configure and enable Sync, which is in
|
|
admin console on same page like the configuration of Federation provider itself. There are 2 types of sync:
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>Full sync</term>
|
|
<listitem>
|
|
<para>
|
|
This will synchronize all LDAP users into Keycloak DB. Those LDAP users, which already exist in Keycloak and were
|
|
changed in LDAP directly will be updated in Keycloak DB (For example if user <literal>Mary Kelly</literal> was changed in LDAP to <literal>Mary Doe</literal>).
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Changed users sync</term>
|
|
<listitem>
|
|
<para>
|
|
This will check LDAP and it will sync into Keycloak just those users, which were created or updated in LDAP from the time of last sync.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
<para>
|
|
In usual cases you may want to trigger full sync at the beginning, so you will import all LDAP users to Keycloak just once. Then you may setup
|
|
periodic sync of changed users, so Keycloak will periodically ask LDAP server for newly created or updated users and backport them to Keycloak DB.
|
|
Also you may want to trigger full sync again after some longer time or setup periodic full sync as well.
|
|
</para>
|
|
<para>In admin console, you can trigger sync directly or you can enable periodic changed or full sync.</para>
|
|
</section>
|
|
<section id="ldap_mappers">
|
|
<title>LDAP/Federation mappers</title>
|
|
<para>
|
|
LDAP mappers are <literal>listeners</literal>, which are triggered by LDAP Federation provider at various points and provide
|
|
another extension point to LDAP integration. They are triggered during import LDAP user into Keycloak, registration Keycloak user back to LDAP or when querying LDAP user from Keycloak.
|
|
When you create LDAP Federation provider, Keycloak will automatically provide set of builtin <literal>mappers</literal> for this provider.
|
|
You are free to change this set and create new mapper or update/delete existing ones.
|
|
</para>
|
|
<para>
|
|
By default, we have those implementation of LDAP federation mapper:
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>User Attribute Mapper</term>
|
|
<listitem>
|
|
<para>
|
|
This allows to specify which LDAP attribute is mapped to which attribute of Keycloak User. So for example you can configure
|
|
that LDAP attribute <literal>mail</literal> is supposed to be mapped to the UserModel attribute <literal>email</literal> in Keycloak database.
|
|
For this mapper implementation, there is always one-to-one mapping (one LDAP attribute mapped to one Keycloak UserModel attribute)
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>FullName Mapper</term>
|
|
<listitem>
|
|
<para>
|
|
This allows to specify that fullname of user, which is saved in some LDAP attribute (usualy <literal>cn</literal> ) will be mapped to
|
|
<literal>firstName</literal> and <literal>lastname</literal> attributes of UserModel. Having <literal>cn</literal> to contain full name of user
|
|
is common case for some LDAP deployments.
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>Role Mapper</term>
|
|
<listitem>
|
|
<para>
|
|
This allows to configure role mappings from LDAP into Keycloak role mappings. One Role mapper can be used to map LDAP roles
|
|
(usually groups from particular branch of LDAP tree) into roles corresponding to either realm roles or client roles of specified client.
|
|
It's not a problem to configure more Role mappers for same LDAP provider. So for example you can specify that role mappings from groups under
|
|
<literal>ou=main,dc=example,dc=org</literal> will be mapped to realm role mappings and role mappings from
|
|
groups under <literal>ou=finance,dc=example,dc=org</literal> will be mapped to client role mappings of client <literal>finance</literal> .
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
<para>By default, there is set of User Attribute mappers to map basic UserModel attributes username, first name, lastname and email to corresponding LDAP attributes. You are free to extend this and provide
|
|
more attribute mappings (For example to street, postalCode etc), delete firstName/lastname mapper and put fullName mapper instead, add role mappers etc.
|
|
Admin console provides tooltips, which should help on how to configure corresponding mappers.
|
|
</para>
|
|
<para>
|
|
We have an example, which is showing LDAP integration and set of base mappers and sample mappers (mappers for street and postalCode) . It's in <literal>examples/ldap</literal>
|
|
in the Keycloak example distribution or demo distribution download. You can also check the example sources directly <ulink url="https://github.com/keycloak/keycloak/blob/master/examples/ldap">here</ulink> .
|
|
</para>
|
|
</section>
|
|
<section>
|
|
<title>Writing your own User Federation Provider</title>
|
|
<para>
|
|
The keycloak examples directory contains an example of a simple User Federation Provider backed by
|
|
a simple properties file. See <literal>examples/providers/federation-provider</literal>. Most of how
|
|
to create a federation provider is explained directly within the example code, but some information is here too.
|
|
</para>
|
|
<para>
|
|
Writing a User Federation Provider starts by implementing the <literal>UserFederationProvider</literal>
|
|
and <literal>UserFederationProviderFactory</literal> interfaces. Please see the Javadoc and example
|
|
for complete details on how to do this. Some important methods of note:
|
|
getUserByUsername() and getUserByEmail() require that you query your federated storage and if the user exists
|
|
create and import the user into Keycloak storage. How much metadata you import is fully up to you. This
|
|
import is done by invoking methods on the object returned <literal>KeycloakSession.userStorage()</literal>
|
|
to add and import user information. The proxy() method will be called whenever Keycloak has found an imported
|
|
UserModel. This allows the federation provider to proxy the UserModel which is useful if you want to support
|
|
external storage updates on demand.
|
|
</para>
|
|
<para>
|
|
After your code is written you must package up all your classes within a JAR file. This jar file must
|
|
contain a file called <literal>org.keycloak.models.UserFederationProviderFactory</literal>
|
|
within the <literal>META-INF/services</literal> directory of the JAR. This file is a list
|
|
of fully qualified classnames of all implementations of <literal>UserFederationProviderFactory</literal>.
|
|
For more details on writing provider implementations and how to deploy to Keycloak refer to the
|
|
<link linkend='providers'>providers</link> section.
|
|
</para>
|
|
</section>
|
|
|
|
</chapter> |