237 lines
17 KiB
Text
237 lines
17 KiB
Text
[[_ldap]]
|
|
|
|
=== LDAP and Active Directory
|
|
|
|
{project_name} comes with a built-in LDAP/AD provider. It is possible to federate multiple different LDAP servers in the same
|
|
{project_name} realm. You can map LDAP user attributes into the {project_name} common user model.
|
|
By default, it maps username, email, first name, and last name, but you are free to configure additional <<_ldap_mappers,mappings>>.
|
|
The LDAP provider also supports password validation via LDAP/AD protocols and different storage, edit, and synchronization modes.
|
|
|
|
To configure a federated LDAP store go to the Admin Console.
|
|
Click on the `User Federation` left menu 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.
|
|
|
|
==== Storage Mode
|
|
|
|
By default, {project_name} will import users from LDAP into the local {project_name} user database. This copy of the user
|
|
is either synchronized on demand, or through a periodic background task.
|
|
The single exception to this is the synchronization of passwords. Passwords are never imported. Their validation is always delegated to the LDAP server.
|
|
The benefits of this approach is that all {project_name} features will work as any extra per-user data that is needed can be stored locally.
|
|
The downside of this approach is that each time that a specific user is queried for the first time, a corresponding {project_name} database insert is performed.
|
|
The import may also have to be synchronized with your LDAP server. However, import synchronization is not necessary in
|
|
the case that the LDAP mappers are configured to always read particular attributes from the LDAP rather than from the database.
|
|
|
|
Alternatively, you can choose not to import users into the {project_name} user database. In this case, the common user model
|
|
that the {project_name} runtime uses is backed only by the LDAP server. This means that if LDAP doesn't support
|
|
a piece of data that a {project_name} feature needs that feature will not work.
|
|
The benefit to this approach is that you do not have the overhead of importing and synchronizing a copy of the LDAP user into the
|
|
{project_name} user database.
|
|
|
|
This storage mode is controled by the `Import Users` switch. Set to `On` to import users.
|
|
|
|
NOTE: If user import is disabled, you cannot save user profile attributes into the {project_name} database. Also you cannot save
|
|
metadata except for user profile metadata that are mapped to the LDAP. The single exception to this are user profile metadata,
|
|
which are mapped to the LDAP. This possibly includes role mappings, group mappings and other metadata based on the configuration
|
|
of your LDAP mappers.
|
|
When the attempt is made to change some of the non-LDAP mapped user data, the update of the user will not be possible. For example
|
|
you will not be able to disable the LDAP mapped user unless the `enabled` flag of the user is mapped to some LDAP
|
|
attribute (which is usually not the case).
|
|
|
|
==== Edit Mode
|
|
|
|
Users, through the <<_account-service, User Account Service>>, and admins through the Admin Console
|
|
have the ability to modify user metadata. Depending on your setup you may or may not have LDAP update privileges. The
|
|
`Edit Mode` configuration option defines the edit policy you have with your LDAP store.
|
|
|
|
READONLY::
|
|
Username, email, first name, last name, and other mapped attributes will be unchangeable.
|
|
{project_name} will show an error anytime anybody tries to update these fields.
|
|
Also, password updates will not be supported.
|
|
|
|
WRITABLE::
|
|
Username, email, first name, last name, and other mapped attributes and passwords can all be updated and will be synchronized automatically with your LDAP store.
|
|
|
|
UNSYNCED::
|
|
Any changes to username, email, first name, last name, and passwords will be stored in {project_name} local storage.
|
|
It is up to you to figure out how to synchronize back to LDAP. This allows {project_name} deployments to support
|
|
updates of user metadata on a read-only LDAP server. This option only applies when you are importing users from LDAP into the local {project_name} user database.
|
|
|
|
NOTE: When the LDAP provider is created, the set of initial <<_ldap_mappers,LDAP mappers>> is created. The mappers are configured on a "best-effort" basis
|
|
based on the chosen combination of the `Vendor`, `Edit Mode`, and `Import Users` switches. For example in case of UNSYNCED edit mode, the mappers are pre-configured
|
|
in a way that a particular user attribute is preferably read from the database instead of from the LDAP. However when you later change the edit mode,
|
|
the mappers configuration will not be changed as it is not easily possible to detect if they were manually changed in the meantime.
|
|
This means that it is recommended NOT to update the `Edit Mode` switch, but rather always decide on `Edit Mode` when creating the
|
|
LDAP provider. This applies for `Import Users` switch as well.
|
|
|
|
==== Other config options
|
|
|
|
Console Display Name::
|
|
Name used when this provider is referenced in the admin console
|
|
|
|
Priority::
|
|
The priority of this provider when looking up users or adding a user.
|
|
|
|
Sync Registrations::
|
|
Does your LDAP support adding new users? Click this switch if you want new users created by {project_name} in the admin console or the registration page
|
|
to be added to LDAP.
|
|
|
|
Allow Kerberos authentication::
|
|
Enable Kerberos/SPNEGO authentication in realm with users data provisioned from LDAP.
|
|
More info in <<_kerberos,Kerberos section>>.
|
|
|
|
Other options::
|
|
The rest of the configuration options should be self explanatory.
|
|
You can hover the mouse pointer over the tooltips in the Admin Console to see some more details about them.
|
|
|
|
==== Connect to LDAP over SSL
|
|
|
|
When you configure a secured connection URL to your LDAP store (for example,`ldaps://myhost.com:636'), {project_name} will use SSL for communication with the LDAP server.
|
|
The important thing is to properly configure a truststore on the {project_name} server side, otherwise {project_name} can't trust the SSL connection to LDAP.
|
|
|
|
The global truststore for the {project_name} can be configured with the Truststore SPI. Please check out the link:{installguide_link}[{installguide_name}] for more details.
|
|
If you do not figure the truststore SPI, the truststore will fall back on the default mechanism provided by Java (either the file provided by system property `javax.net.ssl.trustStore`
|
|
or the cacerts file from the JDK if the system property is not set).
|
|
|
|
There is a configuration property `Use Truststore SPI` in the LDAP federation provider configuration, where you can choose whether the Truststore SPI is used.
|
|
By default, the value is `Only for ldaps`, which is fine for most deployments. The Truststore SPI will only be used
|
|
if the connection URL to LDAP starts with `ldaps`.
|
|
|
|
==== Sync of LDAP users to {project_name}
|
|
|
|
If you enable the Import Users option, the LDAP Provider will automatically take care of synchronization (import) of needed LDAP users into the {project_name} local database.
|
|
As users log in, the LDAP provider will import the LDAP user
|
|
into the {project_name} database and then authenticate against the LDAP password. This is the only time users will be imported.
|
|
If you go to the `Users` left menu item in the Admin Console and click the `View all users` button, you will only see those LDAP users that
|
|
have been authenticated at least once by {project_name}. It is implemented this way so that this operation does not trigger an import of the entire LDAP user database.
|
|
|
|
If you want to sync all LDAP users into the {project_name} database, you may configure and enable the `Sync Settings` on the LDAP provider configuration page.
|
|
Two types of synchronization exist:
|
|
|
|
Periodic Full sync::
|
|
This type will synchronize all LDAP users into the {project_name} database.
|
|
Those LDAP users, which already exist in {project_name} and were changed in LDAP directly will be updated in the {project_name} database. For example, the user `Mary Kelly` was changed in LDAP to `Mary Smith`.
|
|
|
|
Periodic Changed users sync::
|
|
When syncing occurs, only those users that were created or updated after the last sync will be updated and/or imported.
|
|
|
|
The best way to handle syncing is to click the `Synchronize all users` button when you first create the LDAP provider,
|
|
then set up a periodic sync of changed users.
|
|
|
|
[[_ldap_mappers]]
|
|
|
|
==== LDAP Mappers
|
|
|
|
LDAP mappers are `listeners`, which are triggered by the LDAP Provider at various points and provide another extension point to LDAP integration.
|
|
They are triggered when a user logs in via LDAP and needs to be imported, during {project_name} initiated registration, or when a user is queried from the Admin Console.
|
|
When you create an LDAP Federation provider, {project_name} will automatically provide set of built-in `mappers` for this provider.
|
|
You are free to change this set and create a new mapper or update/delete existing ones.
|
|
|
|
User Attribute Mapper::
|
|
This allows you to specify which LDAP attribute is mapped to which attribute of {project_name} user.
|
|
So, for example, you can configure that LDAP attribute `mail` to the attribute `email` in the {project_name} database.
|
|
For this mapper implementation, there is always a one-to-one mapping (one LDAP attribute is mapped to one {project_name} attribute)
|
|
|
|
FullName Mapper::
|
|
This allows you to specify that the full name of the user, which is saved in some LDAP attribute (usually `cn` ) will be mapped to `firstName` and `lastname` attributes in the {project_name} database.
|
|
Having `cn` to contain full name of user is a common case for some LDAP deployments.
|
|
|
|
NOTE: When registering new users in {project_name} and `Sync Registrations` is ON for the LDAP provider, the fullName mapper
|
|
allows the possibility of fallback to the username. This fallback is especially useful in case of the Microsoft Active Directory. The common
|
|
setup for the MSAD is to configure `cn` LDAP attribute as fullName and at the same time, the `cn` is usually used as `RDN LDAP Attribute`
|
|
in the configuration of the LDAP provider. With this setup, the fallback to the username will be used. For example when you create
|
|
{project_name} user "john123" and leave firstName and lastName empty, then fullname mapper will save "john123" as the value of the `cn` in LDAP.
|
|
When you later enter "John Doe" for firstName and lastName, the fullname mapper will update LDAP `cn` to the value "John Doe" as
|
|
fallback to the username will not be needed anymore.
|
|
|
|
Hardcoded Attribute Mapper::
|
|
This mapper adds a hardcoded attribute value to each {project_name} user linked with LDAP.
|
|
This mapper can also force the values for the `enabled` or `emailVerified` user properties.
|
|
|
|
Role Mapper::
|
|
This allows you to configure role mappings from LDAP into {project_name} role mappings.
|
|
One Role mapper can be used to map LDAP roles (usually groups from a particular branch of LDAP tree) into roles corresponding to either realm roles or client roles of a specified client.
|
|
It's not a problem to configure more Role mappers for the same LDAP provider.
|
|
So for example you can specify that role mappings from groups under
|
|
`ou=main,dc=example,dc=org` will be mapped to realm role mappings and role mappings from groups under
|
|
`ou=finance,dc=example,dc=org` will be mapped to client role mappings of client `finance`.
|
|
|
|
Hardcoded Role Mapper::
|
|
This mapper will grant a specified {project_name} role to each {project_name} user from the LDAP provider.
|
|
|
|
Group Mapper::
|
|
This allows you to map LDAP groups from a particular branch of an LDAP tree into groups in {project_name}.
|
|
It will also propagate user-group mappings from LDAP into user-group mappings in {project_name}.
|
|
|
|
MSAD User Account Mapper::
|
|
This mapper is specific to Microsoft Active Directory (MSAD). It's able to tightly integrate the MSAD user account state
|
|
into the {project_name} account state (account enabled, password is expired, and so on).
|
|
It is using the `userAccountControl` and `pwdLastSet` LDAP attributes, which are both specific to MSAD and are not LDAP standard.
|
|
For example if `pwdLastSet` is `0`, the {project_name} user is required to update their password
|
|
and there will be an UPDATE_PASSWORD required action added to the user. If `userAccountControl` is
|
|
`514` (disabled account) the {project_name} user is disabled as well.
|
|
|
|
Certificate Mapper::
|
|
This mapper is specific for mapping X.509 certificates. It will generally be used in conjunction with X.509 authentication
|
|
and `Full certificate in PEM format` as an identity source.
|
|
It behaves the same way as the `User Attribute Mapper`, but allows {project_name} to filter for an LDAP attribute which stores
|
|
a certificate in either PEM or DER format. It is generally advised to enable `Always Read Value From LDAP` with this mapper.
|
|
|
|
By default, there are User Attribute mappers that map basic {project_name} user attributes like username, firstname, lastname, and email to corresponding LDAP attributes.
|
|
You are free to extend these and provide additional attribute mappings.
|
|
Admin console provides tooltips, which should help with configuring the corresponding mappers.
|
|
|
|
[[_ldap_password_hashing]]
|
|
==== Password Hashing
|
|
|
|
When the password of user is updated from {project_name} and sent to LDAP, it is always sent in plain-text. This is different from
|
|
updating the password to built-in {project_name} database, when the hashing and salting is applied to the password before it is sent to DB.
|
|
In the case of LDAP, the {project_name} relies on the LDAP server to provide hashing and salting of passwords.
|
|
|
|
LDAP servers such as Microsoft Active Directory, RHDS or FreeIPA provide this by default. Others such as OpenLDAP or ApacheDS may store the passwords
|
|
in plain-text by default unless you use the _LDAPv3 Password Modify Extended Operation_ as per *RFC3062*. The LDAPv3 Password Modify Extended Operation
|
|
must be enabled explicitly in the LDAP configuration page. See the documentation of your LDAP server for more details.
|
|
|
|
WARNING: Always verify that user passwords are properly hashed and not stored as plaintext by inspecting a changed
|
|
directory entry using `ldapsearch` and base64 decode the `userPassword` attribute value.
|
|
|
|
[[_ldap_troubleshooting]]
|
|
==== Troubleshooting
|
|
|
|
- It is useful to increase the logging level to TRACE for the category `org.keycloak.storage.ldap`. You increase this level in the logging
|
|
subsystem in the `standalone(-ha).xml` file. With this setting, many logging messages are sent
|
|
to the `server.log` file in the `TRACE` level, including the logging for all queries to the LDAP server and the parameters, which were
|
|
used to send the queries. When you are creating any LDAP question on user forum or JIRA, consider attaching the server log with
|
|
enabled TRACE logging. If it is too big, the good alternative is to include just the snippet from server log with the messages, which were
|
|
added to the log during the operation, which causes the issues to you.
|
|
|
|
|
|
- When you create LDAP provider, message appear in the server log in the INFO level starting with:
|
|
```
|
|
Creating new LDAP Store for the LDAP storage provider: ...
|
|
```
|
|
It shows the configuration of your LDAP provider. Before you are asking the questions or reporting bugs, it will be nice to include this
|
|
message to show your LDAP configuration. Eventually feel free to replace some config changes, which you do not want to include, with some
|
|
placeholder values. One example is `bindDn=some-placeholder` . For `connectionUrl`, feel free to replace it as well, but it is generally
|
|
useful to include at least the protocol, which was used (`ldap` vs `ldaps`)`. Similarly it can be useful to include the details for
|
|
configuration of your LDAP mappers, which are displayed with the message like this at the DEBUG level:
|
|
```
|
|
Mapper for provider: XXX, Mapper name: YYY, Provider: ZZZ ...
|
|
```
|
|
Note those messages are displayed just with the enabled DEBUG logging.
|
|
|
|
- For tracking the performance or connection pooling issues, consider setting the value of property `Connection Pool Debug Level` of
|
|
the LDAP provider to value `all`. This will add lots of additional messages to server log with the included logging for the LDAP connection
|
|
pooling. This can be used to track the issues related to connection pooling or performance.
|
|
|
|
NOTE: After changing the configuration of connection pooling, you may need to restart the Keycloak server to enforce re-initialization
|
|
of the LDAP provider connection.
|
|
|
|
If no more messages appear for connection pooling even after server restart, it can indicate that connection pooling does not work
|
|
with your LDAP server.
|
|
|
|
- For the case of reporting LDAP issue, you may consider to attach some part of your LDAP tree with the target data, which causes issues
|
|
in your environment. For example if login of some user takes lot of time, you can consider attach his LDAP entry showing count of `member` attributes
|
|
of various "group" entries. In this case, it might be useful to add if those group entries are mapped to some Group LDAP mapper (or Role LDAP Mapper)
|
|
in {project_name} etc.
|