{project_name} includes an LDAP/AD provider. You can federate multiple different LDAP servers in one {project_name} realm and map LDAP user attributes into the {project_name} common user model.
By default, {project_name} maps the username, email, first name, and last name of the user account, but you can also configure additional <<_ldap_mappers,mappings>>. {project_name}'s LDAP/AD provider supports password validation using LDAP/AD protocols and storage, edit, and synchronization modes.
{project_name} imports users from LDAP into the local {project_name} user database. This copy of the user database synchronizes on-demand or through a periodic background task. An exception exists for synchronizing passwords. {project_name} never imports passwords. Password validation always occurs on the LDAP server.
The advantage of synchronization is that all {project_name} features work efficiently because any required extra per-user data is stored locally. The disadvantage is that each time {project_name} queries a specific user for the first time, {project_name} performs a corresponding database insert.
You can synchronize the import with your LDAP server. Import synchronization is unnecessary when LDAP mappers always read particular attributes from the LDAP rather than the database.
You can use LDAP with {project_name} without importing users into the {project_name} user database. The LDAP server backs up the common user model that the {project_name} runtime uses. If LDAP does not support data that a {project_name} feature requires, that feature will not work. The advantage of this approach is that you do not have the resource usage of importing and synchronizing copies of LDAP users into the {project_name} user database.
The *Import Users* switch on the LDAP configuration page controls this storage mode. To import users, toggle this switch to *ON*.
[NOTE]
====
If you disable *Import Users*, you cannot save user profile attributes into the {project_name} database. Also, you cannot save metadata except for user profile metadata mapped to the LDAP. This metadata can include role mappings, group mappings, and other metadata based on the LDAP mappers' configuration.
When you attempt to change the non-LDAP mapped user data, the user update is not possible. For example, you cannot disable the LDAP mapped user unless the user's `enabled` flag maps to an LDAP attribute.
Users and admins can modify user metadata, users through the <<_account-service, Account Console>>, and administrators through the Admin Console. The `Edit Mode` configuration on the LDAP configuration page defines the user's LDAP update privileges.
You cannot change the username, email, first name, last name, and other mapped attributes. {project_name} shows an error anytime a user attempts to update these fields. Password updates are not supported.
You can change the username, email, first name, last name, and other mapped attributes and passwords and synchronize them automatically with the LDAP store.
{project_name} stores changes to the username, email, first name, last name, and passwords in {project_name} local storage, so the administrator must synchronize this data back to LDAP. In this mode, {project_name} deployments can update user metadata on read-only LDAP servers. This option also applies when importing users from LDAP into the local {project_name} user database.
When {project_name} creates the LDAP provider, {project_name} also creates a set of initial <<_ldap_mappers,LDAP mappers>>. {project_name} configures these mappers based on a combination of the *Vendor*, *Edit Mode*, and *Import Users* switches. For example, when edit mode is UNSYNCED, {project_name} configures the mappers to read a particular user attribute from the database and not from the LDAP server. However, if you later change the edit mode, the mapper's configuration does not change because it is impossible to detect if the configuration changes changed in UNSYNCED mode. Decide the *Edit Mode* when creating the LDAP provider. This note applies to *Import Users* switch also.
When you configure a secure connection URL to your LDAP store (for example,`ldaps://myhost.com:636`), {project_name} uses SSL to communicate with the LDAP server. Configure a truststore on the {project_name} server side so that {project_name} can trust the SSL connection to LDAP - see https://www.keycloak.org/server/keycloak-truststore[Configuring a Truststore] {section}.
If you set the *Import Users* option, the LDAP Provider handles importing LDAP users into the {project_name} local database. The first time a user logs in or is returned as part of a user query (e.g. using the search field in the admin console), the LDAP provider imports the LDAP user into the {project_name} database. During authentication, the LDAP password is validated.
This type synchronizes all LDAP users into the {project_name} database. The LDAP users already in {project_name}, but different in LDAP, directly update in the {project_name} database.
The best way to synchronize is to click *Synchronize all users* when you first create the LDAP provider, then set up periodic synchronization of changed users.
LDAP mappers are `listeners` triggered by the LDAP Provider. They provide another extension point to LDAP integration. LDAP mappers are triggered when:
When you create an LDAP Federation provider, {project_name} automatically provides a set of `mappers` for this provider. This set is changeable by users, who can also develop mappers or update/delete existing ones.
This mapper specifies which LDAP attribute maps to the attribute of the {project_name} user. For example, you can configure the `mail` LDAP attribute to the `email` attribute in the {project_name} database. For this mapper implementation, a one-to-one mapping always exists.
This mapper specifies the full name of the user. {project_name} saves the name in an LDAP attribute (usually `cn`) and maps the name to the `firstName` and `lastname` attributes in the {project_name} database. Having `cn` to contain the full name of the user is common for LDAP deployments.
When you register new users in {project_name} and `Sync Registrations` is ON for the LDAP provider, the fullName mapper permits falling back to the username. This fallback is useful when using Microsoft Active Directory (MSAD). The common setup for MSAD is to configure the `cn` LDAP attribute as fullName and, at the same time, use the `cn` LDAP attribute as the `RDN LDAP Attribute` in the LDAP provider configuration. With this setup, {project_name} falls back to the username. For example, if you create {project_name} user "john123" and leave firstName and lastName empty, then the fullname mapper saves "john123" as the value of the `cn` in LDAP. When you enter "John Doe" for firstName and lastName later, the fullname mapper updates LDAP `cn` to the "John Doe" value as falling back to the username is unnecessary.
This mapper adds a hardcoded attribute value to each {project_name} user linked with LDAP. This mapper can also force values for the `enabled` or `emailVerified` user properties.
This mapper configures role mappings from LDAP into {project_name} role mappings. A single role mapper can map LDAP roles (usually groups from a particular branch of the LDAP tree) into roles corresponding to a specified client's realm roles or client roles. You can configure more Role mappers for the same LDAP provider. For example, you can specify that role mappings from groups under `ou=main,dc=example,dc=org` map to realm role mappings, and role mappings from groups under `ou=finance,dc=example,dc=org` map to client role mappings of client `finance`.
This mapper maps LDAP groups from a branch of an LDAP tree into groups within {project_name}. This mapper also propagates user-group mappings from LDAP into user-group mappings in {project_name}.
This mapper is specific to Microsoft Active Directory (MSAD). It can integrate the MSAD user account state into the {project_name} account state, such as enabled account or expired password. This mapper uses the `userAccountControl`, and `pwdLastSet` LDAP attributes, specific to MSAD and are not the LDAP standard. For example, if the value of `pwdLastSet` is `0`, the {project_name} user must update their password. The result is an UPDATE_PASSWORD required action added to the user. If the value of `userAccountControl` is `514` (disabled account), the {project_name} user is disabled.
This mapper maps X.509 certificates. {project_name} uses it in conjunction with X.509 authentication and `Full certificate in PEM format` as an identity source. This mapper behaves similarly to the `User Attribute Mapper`, but {project_name} can filter for an LDAP attribute storing a PEM or DER format certificate. Enable `Always Read Value From LDAP` with this mapper.
User Attribute mappers that map basic {project_name} user attributes, such as username, firstname, lastname, and email, to corresponding LDAP attributes. You can extend these and provide your own additional attribute mappings. The Admin Console provides tooltips to help with configuring the corresponding mappers.
When {project_name} updates a password, {project_name} sends the password in plain-text format. This action is different from updating the password in the built-in {project_name} database, where {project_name} hashes and salts the password before sending it to the database. For LDAP, {project_name} relies on the LDAP server to hash and salt the password.
By default, LDAP servers such as MSAD, RHDS, or FreeIPA hash and salt passwords. Other LDAP servers such as OpenLDAP or ApacheDS store the passwords in plain-text unless you use the _LDAPv3 Password Modify Extended Operation_ as described in https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.3[RFC3062]. Enable the LDAPv3 Password Modify Extended Operation in the LDAP configuration page. See the documentation of your LDAP server for more details.
For more efficiency when managing LDAP connections and to improve performance when handling multiple connections, you can
enable connection pooling. By doing that, when a connection is closed, it will be returned to the pool for future use therefore
reducing the cost of creating new connections all the time.
The LDAP connection pool configuration is configured using the following system properties:
[cols="2*", options="header"]
|===
|Name
|Description
| `com.sun.jndi.ldap.connect.pool.authentication` | A list of space-separated authentication types of connections that may be pooled. Valid types are "none", "simple", and "DIGEST-MD5"
| `com.sun.jndi.ldap.connect.pool.initsize` | The string representation of an integer that represents the number of connections per connection identity to create when initially creating a connection for the identity
| `com.sun.jndi.ldap.connect.pool.maxsize` | The string representation of an integer that represents the maximum number of connections per connection identity that can be maintained concurrently
| `com.sun.jndi.ldap.connect.pool.prefsize` | The string representation of an integer that represents the preferred number of connections per connection identity that should be maintained concurrently
| `com.sun.jndi.ldap.connect.pool.timeout` | The string representation of an integer that represents the number of milliseconds that an idle connection may remain in the pool without being closed and removed from the pool
| `com.sun.jndi.ldap.connect.pool.protocol` | A list of space-separated protocol types of connections that may be pooled. Valid types are "plain" and "ssl"
| `com.sun.jndi.ldap.connect.pool.debug` | A string that indicates the level of debug output to produce. Valid values are "fine" (trace connection creation and removal) and "all" (all debugging information)
|===
For more details, see the link:https://docs.oracle.com/javase/jndi/tutorial/ldap/connect/config.html[Java LDAP Connection Pooling Configuration] documentation.
To set any of these properties, you can set the `JAVA_OPTS_APPEND` environment variable:
- For tracking the performance or connection pooling issues, consider setting the value of property `com.sun.jndi.ldap.connect.pool.debug` to `all`. This change adds many additional messages to the server log with the included logging for the LDAP connection
pooling. As a result, you can track the issues related to connection pooling or performance. For more details, see link:#_ldap_connection_pool[Configuring the connection pool].