Configuring LDAP user registries in Liberty
You can configure one or more Lightweight Directory Access Protocol (LDAP) servers with Liberty for authentication.
The latest documentation about configuring an LDAP user registry for Liberty is available on the Open Liberty website.
Before you begin
About this task
You can use an existing LDAP server for application authentication on Liberty. You need to add the
appSecurity-2.0
feature to the server.xml file and specify the
ldapRegistry-3.0
feature in the server.xml file, and the
configuration information for connecting to the LDAP server.
Procedure
-
Add the
appSecurity-2.0
andldapRegistry-3.0
Liberty features to the server.xml file. - Optional:
To communicate with an SSL-enabled LDAP server, add the
transportSecurity-1.0
Liberty feature in the server.xml file. - Optional:
Copy the truststore to the server configuration directory.
For example, you can use the
${server.config.dir}
variable.For SSL communication with an LDAP server to succeed, the Signer certificate for the LDAP server must be added to the truststore that is referenced by the sslRef attribute of the
<ldapRegistry>
element. In the following examples, the Signer certificate must be added to theLdapSSLTrustStore.jks
. -
Configure the LDAP entry for the server.
If you do not want SSL for the LDAP server, remove all SSL and keystore-related lines from the following examples.
You configure the LDAP server in the server.xml file or by using the WebSphere® Application Server Developer Tools for Eclipse. There are several security configuration examples on the Open Liberty website for reference when configuring security for your applications on Liberty.- For IBM® Directory
Server:
<ldapRegistry id="ldap" realm="SampleLdapIDSRealm" host="ldapserver.mycity.mycompany.com" port="389" ignoreCase="true" baseDN="o=mycompany,c=us" ldapType="IBM Tivoli Directory Server" sslEnabled="true" sslRef="LDAPSSLSettings"> <idsFilters userFilter="(&(uid=%v)(objectclass=ePerson))" groupFilter="(&(cn=%v)(|(objectclass=groupOfNames) (objectclass=groupOfUniqueNames) (objectclass=groupOfURLs)))" userIdMap="*:uid" groupIdMap="*:cn" groupMemberIdMap="ibm-allGroups:member;ibm-allGroups:uniqueMember; groupOfNames:member;groupOfUniqueNames:uniqueMember"> </idsFilters> </ldapRegistry> <ssl id="LDAPSSLSettings" keyStoreRef="LDAPKeyStore" trustStoreRef="LDAPTrustStore" /> <keyStore id="LDAPKeyStore" location="${server.config.dir}/LdapSSLKeyStore.jks" type="JKS" password="{xor}CDo9Hgw=" /> <keyStore id="LDAPTrustStore" location="${server.config.dir}/LdapSSLTrustStore.jks" type="JKS" password="{xor}CDo9Hgw=" />
- For Microsoft Active Directory Server:
<ldapRegistry id="ldap" realm="SampleLdapADRealm" host="ldapserver.mycity.mycompany.com" port="389" ignoreCase="true" baseDN="cn=users,dc=adtest,dc=mycity,dc=mycompany,dc=com" bindDN="cn=testuser,cn=users,dc=adtest,dc=mycity,dc=mycompany,dc=com" bindPassword="testuserpwd" ldapType="Microsoft Active Directory" sslEnabled="true" sslRef="LDAPSSLSettings"> <activedFilters userFilter="(&(sAMAccountName=%v)(objectcategory=user))" groupFilter="(&(cn=%v)(objectcategory=group))" userIdMap="user:sAMAccountName" groupIdMap="*:cn" groupMemberIdMap="memberOf:member" > </activedFilters> </ldapRegistry> <ssl id="LDAPSSLSettings" keyStoreRef="LDAPKeyStore" trustStoreRef="LDAPTrustStore" /> <keyStore id="LDAPKeyStore" location="${server.config.dir}/LdapSSLKeyStore.jks" type="JKS" password="{xor}CDo9Hgw=" /> <keyStore id="LDAPTrustStore" location="${server.config.dir}/LdapSSLTrustStore.jks" type="JKS" password="{xor}CDo9Hgw=" />
If you use the WebSphere Application Server Developer Tools for Eclipse, the
bindPassword
password is encoded for you automatically. If you edit the server.xml file directly, you can use the securityUtility encode command to encode thebindPassword
password for you. ThesecurityUtility
command-line tool is available in the$INSTALL_ROOT/bin
directory. When you run the securityUtility encode command, you either supply the password to encode as an input from the command line or, if no arguments are specified, the tool prompts you for the password. The tool then outputs the encoded value. Copy the value output by the tool, and use that value for thebindPassword
password. - For IBM® Directory
Server:
- Optional:
Configure certificate filter mode for the LDAP server.
For more information about certificate map mode in Liberty, see LDAP certificate map mode.<ldapRegistry id="LDAP" realm="SampleLdapIDSRealm" host="myldap.ibm.com" port="389" ignoreCase="true" baseDN="o=ibm,c=us" ldapType="IBM Tivoli Directory Server" searchTimeout="8m" certificateMapMode="CERTIFICATE_FILTER" certificateFilter="uid=${SubjectCN}"> <idsFilters userFilter="(&(uid=%v)(objectclass=ePerson))" groupFilter="(&(cn=%v)(|(objectclass=groupOfNames) (objectclass=groupOfUniqueNames)(objectclass=groupOfURLs)))" userIdMap="*:uid" groupIdMap="*:cn" groupMemberIdMap="ibm-allGroups:member;ibm-allGroups:uniqueMember; groupOfNames:member;groupOfUniqueNames:uniqueMember"> </idsFilters> </ldapRegistry>
- Optional:
You can define mapping between LDAP attributes and the user registry schema attributes.
After the mapping is configured, when you use the user registry attribute for any operation for which the mapping is defined, the user registry attribute value will be the value of the LDAP attribute. In the following example, you can see that the mapping is defined for the LDAP attribute
<userPassword>
with the user registry property <password> in the server.xml file. The<defaultValue>
attribute is optional.<ldapRegistry id="LDAP" realm="SampleLdapIDSRealm" host="myldap.ibm.com" port="389" ignoreCase="true" baseDN="o=ibm,c=us" ldapType="IBM Tivoli Directory Server" searchTimeout="8m"> <attributeConfiguration> <attribute name="userPassword" propertyName="password" entityType="PersonAccount" defaultValue="xyz123"/> </attributeConfiguration> </ldapRegistry>
-
Add
ldapEntityType
elements to define LDAP object classes.-
Add the
ObjectClass
attributes orObjectCategory
attributes for your person or group entities.The defined
ObjectClass
orObjectCategory
are added to the user or group filter on searches. Examples ofObjectClass
includeinetOrgPerson
orgroupOfNames
.<ldapEntityType name="PersonAccount"> <objectClass>ePerson</objectClass> </ldapEntityType> <ldapEntityType name="Group"> <objectClass>groupOfNames</objectClass> </ldapEntityType>
If the correct
ObjectClass
orObjectCategory
are not defined, aClassCastException
can occur. Examples ofObjectClass
includeinetOrgPerson
orgroupOfNames
. In other cases, the user is not found or a request togetSecurityName
returns anempty
string.For example,
java.lang.ClassCastException: com.ibm.wsspi.security.wim.model.Entity
is not compatible withcom.ibm.wsspi.security.wim.model.LoginAccount
.
-
Add the
- Optional:
Add search bases or user or group search filters to
ldapEntityType
elements.-
Add a search base
A search base specifies the sub tree of the LDAP server for the search call of the given entity type, which overrides the base DN in search operations. For example, if the base DN is
o=ibm,c=us
and the search base for the PersonAccount entity type is defined asou=iUsers,o=ibm,c=us
, then all search calls for PersonAccount are made under sub treeou=iUsers,o=ibm,c=us
.You can define a group ldapEntityType
searchBase
asou=iGroups,o=ibm,c=us
. With this definition, entities in other sub trees, such asou=iThings,o=ibm,c=us
, are ignored.Important: Multiple search bases should be used instead of creating multiple LDAP registries for the same LDAP server with different baseDNs.<ldapEntityType name="PersonAccount"> <objectClass>ePerson</objectClass> <searchBase>ou=Users,o=ibm,c=us</searchBase> </ldapEntityType> <ldapEntityType name="Group"> <objectClass>groupOfNames</objectClass> <searchBase>ou=Group,o=ibm,c=us</searchBase> </ldapEntityType>
-
Add a search filter.
A custom LDAP search expression used while searching for entity types. For example,
searchFilter="(|(ObjectCategory=User)(ObjectClass=User))"
.
-
Add a search base
- Optional:
You can define mapping between LDAP attributes and the user registry
<externalId>
attribute.You can define mapping between LDAP attributes and the user registry
<externalId>
attribute. After the mapping is configured, when you use the user registry<externalId>
attribute for any operation, the value will be equivalent to the value of the LDAP attribute that is mapped. The following example code shows the mapping that is defined for the user registry<externalId>
attribute with the LDAP<distinguishedName>
attribute for the entity type<PersonAccount>
. The<autoGenerate>
attribute is optional, and the value is false by default.<ldapRegistry id="LDAP" realm="SampleLdapIDSRealm" host="myldap.ibm.com" port="389" ignoreCase="true" baseDN="o=ibm,c=us" ldapType="IBM Tivoli Directory Server" searchTimeout="8m"> <attributeConfiguration> <externalIdAttribute name="distinguishedName" entityType="PersonAccount" autoGenerate="false"></externalIdAttribute> </attributeConfiguration> </ldapRegistry>
- Optional:
Configure failover for multiple LDAP servers.
<ldapRegistry id="LDAP" realm="SampleLdapIDSRealm" host="ldapserver1.mycity.mycompany.com" port="389" ignoreCase="true" baseDN="o=ibm,c=us" ldapType="IBM Tivoli Directory Server" idsFilters="ibm_dir_server"> <failoverServers name="failoverLdapServersGroup1"> <server host="ldapserver2.mycity.mycompany.com" port="389" /> <server host="ldapserver3.mycity.mycompany.com" port="389" /> </failoverServers> <failoverServers name="failoverLdapServersGroup2"> <server host="ldapserver4.mycity.mycompany.com" port="389" /> </failoverServers> </ldapRegistry> <idsLdapFilterProperties id="ibm_dir_server" userFilter="(&(uid=%v)(objectclass=ePerson))" groupFilter="(&(cn=%v)(|(objectclass=groupOfNames) (objectclass=groupOfUniqueNames)(objectclass=groupOfURLs)))" userIdMap="*:uid" groupIdMap="*:cn" groupMemberIdMap="ibm-allGroups:member;ibm-allGroups:uniqueMember; groupOfNames:member;groupOfUniqueNames:uniqueMember"> </idsLdapFilterProperties>
For more information about the
ldapRegistry
andfailoverServers
elements, see LDAP User Registry. - Optional:
Configure multiple LDAP registries. If multiple LDAP registries are configured in the
server.xml file, they are federated automatically. Ensure that the users are
unique across all federated repositories, otherwise the user registry operations are not
successful.
Note: When you use multiple federated LDAP repositories, each repository must define a unique baseDN.
<ldapRegistry host="ldapserver1.mycity1.mycompany.com" baseDN="o=mycompany,c=us" port="123" ldapType="IBM Tivoli Directory Server"> </ldapRegistry> <ldapRegistry host="ldapserver2.mycity2.mycompany.com" baseDN="cn=users,dc=secfvt2,dc=mycity2,dc=mycompany,dc=com" port="456" ldapType="Microsoft Active Directory" bindDN="cn=testuser,cn=users,dc=secfvt2,dc=mycity2,dc=mycompany,dc=com" bindPassword="{xor}KzosKyosOi0vKDs="> </ldapRegistry>
Note:- It is best practice, but not mandatory, to specify the
federatedRepository
element to federate multiple LDAP registries because they are federated automatically. If the federatedRepository element is specified to configure theparticipatingBaseEntry
andprimaryRealm
elements, then the user registry operations are performed only on the repositories that are defined in theprimaryRealm
element. You can define the input and output property mappings for different user registry APIs under theprimaryRealm
element. - The name attribute of the
participatingBaseEntry
element must be the same as the value of baseDN attribute that is specified in theldapRegistry
element. In the example follows, the baseDN and name attributes are configured for the LDAP registry on the host ldapserver1.mycity1.mycompany.com. The value of baseDN attribute must be the same as that of sub tree in your LDAP server and the value of name attribute must be the name of that sub tree in the federated user registry. It is optional to specify the name attribute. By default, the name attribute uses the same value as the baseDN attribute. If the name attribute is specified in theldapRegistry
element, then the name attribute in theparticipatingBaseEntry
element must use the same value as the name attribute in theldapRegistry
element.
<ldapRegistry host="ldapserver1.mycity1.mycompany.com" baseDN="o=mycompany,ou=myou,c=us" port="123" ldapType="IBM Tivoli Directory Server" name="o=mybaseentry"> </ldapRegistry> <ldapRegistry host="ldapserver2.mycity2.mycompany.com" baseDN="cn=users,dc=secfvt2,dc=mycity2,dc=mycompany,dc=com" port="456" ldapType="Microsoft Active Directory" bindDN="cn=testuser,cn=users,dc=secfvt2,dc=mycity2,dc=mycompany,dc=com" bindPassword="{xor}KzosKyosOi0vKDs="> </ldapRegistry> <federatedRepository> <primaryRealm name="RealmName" delimiter="@" allowOpIfRepoDown="true"> <participatingBaseEntry name="o=mybaseentry"/> <participatingBaseEntry name="cn=users,dc=secfvt2,dc=mycity2,dc=mycompany,dc=com"/> <uniqueUserIdMapping inputProperty="uniqueName" outputProperty="uniqueName"/> <userSecurityNameMapping inputProperty="principalName" outputProperty="principalName"/> <userDisplayNameMapping inputProperty="principalName" outputProperty="principalName"/> <uniqueGroupIdMapping inputProperty="uniqueName" outputProperty="uniqueName"/> <groupSecurityNameMapping inputProperty="cn" outputProperty="cn"/> <groupDisplayNameMapping inputProperty="cn" outputProperty="cn"/> </primaryRealm> </federatedRepository>
For more information about the federated
ldapRegistry
elements, see LDAP User Registry. - It is best practice, but not mandatory, to specify the
- Optional:
You can configure other optional attributes for the LDAP registry, such as
contextPool or ldapCache, as given in the following
example:
<ldapRegistry id="IBMDirectoryServerLDAP" realm="SampleLdapIDSRealm" host="host.domain.com" port="389" ignoreCase="true" baseDN="o=domain,c=us" bindDN="cn=testuser,o=domain,c=us" bindPassword="mypassword" ldapType="IBM Tivoli Directory Server" searchTimeout="8m"> <contextPool enabled="true" initialSize="1" maxSize="0" timeout="0s" waitTime="3000ms" preferredSize="3"/> <ldapCache> <attributesCache size="4000" timeout="1200s" enabled="true" sizeLimit="2000"/> <searchResultsCache size="2000" timeout="600s" enabled="true" resultsSizeLimit="1000"/> </ldapCache> </ldapRegistry>
Note:- Federated user registry uses the context pooling mechanism to improve the performance of concurrent access to an LDAP server. Context pooling works at a higher level than the connection pooling. Each context entry in the context pool corresponds to a socket connection to the LDAP server. The bind credentials that are used by this pool are specified when you configure the LDAP registry.
- Federated repository uses the cache mechanism for performance enhancement. It caches information
about the LDAP users and groups based on the user operations performed. For example, if you perform
a search operation on the LDAP users and groups, the result of the operation is cached. You can
enable the
ldapCache
element in the server.xml file as shown in the previous example.
Troubleshooting tip: To troubleshoot any LDAP authentication issues, use the following trace specifications in the bootstrap.properties file:com.ibm.ws.security.wim.*=all:com.ibm.websphere.security.wim.*=all
- Optional:
The SSL configuration that is used to connect to the LDAP server can be determined in the SSL
configuration rather than by being specified with the
sslRef
attribute. ThesslEnabled
attribute needs to be set to true.If
sslRef
is not specified the SSL code looks to see if an outbound filter that matches the LDAP host and port, or if the SSL outbound default should be used. For more information on the outbound SSL options, see Configuring SSL Settings for outbound communications. For more information on outbound filters, see Outbound filters for SSL configurations<ldapRegistry id="ldap" realm="SampleLdapIDSRealm" host="ldapserver.mycity.mycompany.com" port="389" ignoreCase="true" baseDN="o=mycompany,c=us" ldapType="IBM Tivoli Directory Server" sslEnabled="true" > <idsFilters userFilter="(&(uid=%v)(objectclass=ePerson))" groupFilter="(&(cn=%v)(|(objectclass=groupOfNames) (objectclass=groupOfUniqueNames)(objectclass=groupOfURLs)))" userIdMap="*:uid" groupIdMap="*:cn" groupMemberIdMap="ibm-allGroups:member;ibm-allGroups:uniqueMember; groupOfNames:member;groupOfUniqueNames:uniqueMember"> </idsFilters> </ldapRegistry>