Chapter 16. LDAP
Prev |  | Next

## Chapter 16. LDAP

### Boleslaw Dawidowicz

`<boleslaw dot dawidowicz at redhat dot com>`

This chapter describes how to setup LDAP support in JBoss Portal

### Note

To be able to fully understand this chapter you should also read JBoss Portal Identity management and Authentication chapters before

## 16.1. How to enable LDAP usage in JBoss Portal

We'll describe here the simple steps that you will need to perform to enable LDAP support in JBoss Portal. For additional information you need to read more about configuration of identity and specific implementations of identity modules

There are two ways to achieve this:

- jboss-porta.sar/META-INF/jboss-service.xml in section:

      <mbean
         code="org.jboss.portal.identity.IdentityServiceControllerImpl"
         name="portal:service=Module,type=IdentityServiceController"
         xmbean-dd=""
         xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">
         <xmbean/>
         <depends>portal:service=Hibernate</depends>
         <attribute name="JndiName">java:/portal/IdentityServiceController</attribute>
         <attribute name="RegisterMBeans">true</attribute>
         <attribute name="ConfigFile">conf/identity/identity-config.xml</attribute>
         <attribute name="DefaultConfigFile">conf/identity/standardidentity-config.xml</attribute>
      </mbean>

  change identity-config.xml to ldap_identity-config.xml

- Swap the names or content of files in jboss-porta.sar/conf/identity/identity-config.xml and jboss-porta.sar/conf/identity/ldap_identity-config.xml

After doing one of the above changes you need to edit configuration file that you choose to use (identity-config.xml or ldap_identity-config.xml) and configure LDAP connection options in section:

    <datasource>
       <name>LDAP</name>
       <config>
          <option>
             <name>host</name>
             <value>jboss.com</value>
          </option>
          <option>
             <name>port</name>
             <value>10389</value>
          </option>
          <option>
             <name>adminDN</name>
             <value>cn=Directory Manager</value>
          </option>
          <option>
             <name>adminPassword</name>
             <value>qpq123qpq</value>
          </option>
       </config>
    </datasource>

You also need to specify options for your LDAP tree (described in configuration documentation) like those:

    <option-group>
       <group-name>common</group-name>
       <option>
          <name>userCtxDN</name>
          <value>ou=People,dc=portal26,dc=jboss,dc=com</value>
       </option>
       <option>
          <name>roleCtxDN</name>
          <value>ou=Roles,dc=portal26,dc=jboss,dc=com</value>
       </option>
    </option-group>

### Note

Under PORTAL_SOURCES/identity/src/resources/example/ you can find a sample ldif that you can use to populate LDAP server and quickly start playing with it.

## 16.2. Configuration of LDAP connection

### 16.2.1. SSL

The setup is very similar to the one described in LdapLoginModule wiki page

You need to modify your identity configuration file and add "protocol"

    <datasource>
       <name>LDAP</name>
       <config>
          ...
          <option>
             <name>protocol</name>
             <value>ssl</value>
          </option>
          ...
       </config>
    </datasource>

Then you need to have LDAP server certificate imported into your keystore. You can use following command:

    keytool -import -file ldapcert.der -keystore ldap.truststore

Now you need to change the settings to use the alternative truststore. That can be done in the properties-service.xml in deploy directory:

    <attribute name="Properties">
       javax.net.ssl.trustStore=../some/path/to/ldap.truststore
       javax.net.ssl.trustStorePassword=somepw
    </attribute>

### 16.2.2. ExternalContext

Instead of configuring your own connection you can use JNDI context federation mechanism in JBoss Application Server. Configuration of ExternalContext is described in JBoss Application Server documentation

When you have ExternalContext configured you can use it in JBoss Portal by providing proper JNDI name in the configuration:

    <datasource>
       <name>LDAP</name>
       <config>
          <option>
             <name>externalContextJndiName</name>
             <value>external/ldap/jboss</value>
          </option>
       </config>
    </datasource>

### Note

When using "externalContextJndiName" you don't need to specify any other option for this datasource

## 16.3. LDAP Identity Modules

JBoss Portal comes with base LDAP implementation of all identity modules.

### 16.3.1. Common settings

For all modules you can set two config options:

- jNDIName - JNDI name under which this module will be registered
- connectionJNDIName - JNDI name under which LDAP datasource is registered

### Note

Most configuration of LDAP identity modules is done in options section by adding module specific options in "common" option-group or in other module specific groups.

### 16.3.2. UserModule

Table 16.1. Comparision of UserModule implementations

Features | UserModule
--- | ---
LDAPUserModuleImpl | LDAPExtUserModuleImpl
User creation | X | -
User removal | X | -
User search | Flat - one level scope | Flexible filter - sub tree scope

#### 16.3.2.1. LDAPUserModuleImpl

This is the base implementation of LDAP UserModule. It supports user creation, but will retrieve users and create them in strictly specified place in LDAP tree.

To enable it in your configuration you should have:

    <module>
       <!--type used to correctly map in IdentityContext registry-->
       <type>User</type>
       <implementation>LDAP</implementation>
       <config/>
    </module>

org.jboss.portal.identity.ldap.LDAPUserModuleImpl configuration option-groups options:

- common:
  - userCtxDN - DN that will be used as context for user searches
  - uidAttributeID - attribute name under which user name is specified. Default value is "uid"
  - passwordAttributeID - attribute name under which user password is specified. Default value is "userPassword"
  - principalDNPrefix and principalDNSuffix
  - searchTimeLimit - The timeout in milliseconds for the user searches. Defaults to 10000 (10 seconds).
- userCreateAttibutes: This option-group defines a set of ldap attributes that will be set on user entry creation. Option name will be used as attribute name, and option values as attribute values. This enables to fulfill LDAP schema requirements.

Example configuration:

    <option-group>
       <group-name>common</group-name>
       <option>
          <name>userCtxDN</name>
          <value>ou=People,o=portal,dc=my-domain,dc=com</value>
       </option>
       <option>
          <name>uidAttributeID</name>
          <value>uid</value>
       </option>
       <option>
          <name>passwordAttributeID</name>
          <value>userPassword</value>
       </option>
    </option-group>
    <option-group>
       <group-name>userCreateAttibutes</group-name>
       <option>
          <name>objectClass</name>
          <!--This objectclasses should work with Red Hat Directory-->
          <value>top</value>
          <value>person</value>
          <value>inetOrgPerson</value>
       </option>
       <!--Schema requires those to have initial value-->
       <option>
          <name>cn</name>
          <value>none</value>
       </option>
       <option>
          <name>sn</name>
          <value>none</value>
       </option>
    </option-group>

#### 16.3.2.2. LDAPExtUserModuleImpl

Aim of this implementation is to give more flexibility for users retrieval. You can specify LDAP filter that will be used for searches. This module doesn't support user creation and removal

To enable it in your configuration you should have:

    <module>
       <!--type used to correctly map in IdentityContext registry-->
       <type>User</type>
       <implementation>LDAP</implementation>
       <class>org.jboss.portal.identity.ldap.LDAPExtUserModuleImpl</class>
       <config/>
    </module

org.jboss.portal.identity.ldap.LDAPExtUserModuleImpl configuration option-groups options:

- common:
  - userCtxDN - DN that will be used as context for user searches. More than one value can be specified.
  - userSearchFilter - ldap filter to search users with. {0} will be substitute with user name. Example filter can look like this: "(uid={0})". This substituion behavior comes from the standard DirContext.search(Name, String, Object, SearchControls cons) method
  - uidAttributeID - attribute name under which user name is specified. Default value is "uid"
  - searchTimeLimit - The timeout in milliseconds for the user searches. Defaults to 10000 (10 seconds).

### 16.3.3. RoleModule

Table 16.2. Comparision of RoleModule implementations

Features | RoleModule
--- | ---
LDAPRoleModuleImpl | LDAPExtRoleModuleImpl
Role creation | X | -
Role removal | X | -
Role search | Flat - one level scope | Flexible filter - sub tree scope

#### 16.3.3.1. LDAPRoleModuleImpl

This is the base implementation of LDAP RoleModule. It supports user creation, but will retrieve roles and create them in strictly specified place in LDAP tree.

To enable it in your configuration you should have:

    <module>
       <!--type used to correctly map in IdentityContext registry-->
       <type>Role</type>
       <implementation>LDAP</implementation>
       <config/>
    </module>

org.jboss.portal.identity.ldap.LDAPRoleModuleImpl configuration option-groups options:

- common:
  - roleCtxDN - DN that will be used as context for role searches.
  - ridAttributeID - attribute name under which role name is specified. Default value is "cn".
  - roleDisplayNameAttributeID - attribute name under which role display name is specified. Default value is "cn".
  - searchTimeLimit - The timeout in milliseconds for the roles searches. Defaults to 10000 (10 seconds).

#### 16.3.3.2. LDAPExtRoleModuleImpl

Aim of this implementation is to give more flexibility for roless retrieval. You can specify LDAP filter that will be used for searches. This module doesn't support role creation and removal

This module doesn't support role creation and removal

To enable it in your configuration you should have:

    <module>
       <!--type used to correctly map in IdentityContext registry-->
       <type>Role</type>
       <implementation>LDAP</implementation>
       <class>org.jboss.portal.identity.ldap.LDAPExtRoleModuleImpl</class>
       <config/>
    </module>

org.jboss.portal.identity.ldap.LDAPExtRoleModuleImpl configuration option-groups options:

- common:
  - roleCtxDN - DN that will be used as context for role searches. More than one value can be specified.
  - roleSearchFilter - ldap filter to search roles with. {0} will be substitute with role name. Example filter can look like this: "(cn={0})". This substituion behavior comes from the standard DirContext.search(Name, String, Object, SearchControls cons) method.
  - ridAttributeID - attribute name under which role name is specified. Default value is "cn".
  - roleDisplayNameAttributeID - attribute name under which role display name is specified. Default value is "cn".
  - searchTimeLimit - The timeout in milliseconds for the roles searches. Defaults to 10000 (10 seconds).
  - searchScope - Sets the search scope to one of the strings. The default is SUBTREE_SCOPE.
    - OBJECT_SCOPE - only search the named roles context.
    - ONELEVEL_SCOPE - search directly under the named roles context.
    - SUBTREE_SCOPE - If the roles context is not a DirContext, search only the object. If the roles context is a DirContext, search the subtree rooted at the named object, including the named object itself.

### Note

In UserModule there are two methods that handle offset/limit (pagination) behaviour.

    /** Get a range of users.*/
    Set findUsers(int offset, int limit) throws IdentityException, IllegalArgumentException;

    /** Get a range of users.*/
    Set findUsersFilteredByUserName(String filter, int offset, int limit)
       throws IdentityException, IllegalArgumentException;

Pagination support is not widely implemented in LDAP servers. Because UserModule implementations rely on JNDI and are targetted to be LDAP server agnostic those methods aren't very effecient. As long as you don't rely on portal user management and use dedicated tools for user provisioning it shouldn't bother you. Otherwise you should consider extending the implementation and providing solution dedicated to your LDAP server.

### 16.3.4. MembershipModule

Table 16.3. Comparision of MembershipModule implementations

Features | MembershipModule
--- | ---
LDAPStaticGroupMembershipModuleImpl | LDAPStaticRoleMembershipModuleImpl
Role assignment stored in LDAP role entry | X | -
Role assignment stored in LDAP user entry | - | X
User/Role relationship creation | X | X

#### 16.3.4.1. LDAPStaticGroupMembershipModuleImpl

This module support tree shape where role entries keep information about users that are their members.

To enable it in your configuration you should have:

    <module>
       <!--type used to correctly map in IdentityContext registry-->
       <type>Membership</type>
       <implementation>LDAP</implementation>
       <config/>
    </module>

org.jboss.portal.identity.ldap.LDAPStaticGroupMembershipModuleImpl configuration option-groups options:

- common:
  - membershipAttributeID - LDAP attribute that defines member users ids. This will be used to retrieved users from role entry.
  - membershipAttributeIsDN - defines if values of attribute defined in membershipAttributeID are fully qualified LDAP DNs.

#### 16.3.4.2. LDAPStaticRoleMembershipModuleImpl

This module support tree shape where user entries keep information about roles that they belong to.

To enable it in your configuration you should have:

    <module>
       <!--type used to correctly map in IdentityContext registry-->
       <type>Membership</type>
       <implementation>LDAP</implementation>
       <class>org.jboss.portal.identity.ldap.LDAPStaticRoleMembershipModuleImpl</class>
       <config/>
    </module>

org.jboss.portal.identity.ldap.LDAPStaticRoleMembershipModuleImpl configuration option-groups options:

- common:
  - membershipAttributeID - LDAP attribute that defines role ids that user belongs to. This will be used to retrieved roles from user entry.
  - membershipAttributeIsDN - defines if values of attribute defined in membershipAttributeID are fully qualified LDAP DNs.

### 16.3.5. UserProfileModule

#### 16.3.5.1. LDAPUserProfileModuleImpl

This is standard implementation that enables to retrieve user properties from atributes in LDAP entries.

To enable it in your configuration you should have:

    <module>
       <type>UserProfile</type>
       <implementation>DELEGATING</implementation>
       <config>
          <option>
             <name>ldapModuleJNDIName</name>
             <value>java:/portal/LDAPUserProfileModule</value>
          </option>
       </config>
    </module>
    <module>
       <type>DBDelegateUserProfile</type>
       <implementation>DB</implementation>
       <config>
          <option>
             <name>randomSynchronizePassword</name>
             <value>true</value>
          </option>
       </config>
    </module>
    <module>
       <type>LDAPDelegateUserProfile</type>
       <implementation>LDAP</implementation>
       <config/>
    </module>

### Note

Using such configuration you will have LDAP MembershipModule along with DB MembershipModule and Delegating MembershipModule. Please read Identity chapter to see why this is important.

org.jboss.portal.identity.ldap.LDAPUserModuleImpl configuration option-groups options:

- common:
  - profileConfigFile - file with user profile configuration. If this option is not set, and we use delegating UserProfileModule, profile configuration will be obtained from it.

## 16.4. LDAP server tree shapes

JBoss Portal supports full user/role management for simple LDAP tree shapes. Some more flexible trees can be supported by LdapExtUserModuleImpl and LdapExtRoleModuleImpl - but without user/role creation and removal capabilities. However if you have complex LDAP tree you should consider using SynchronizingLoginModule described in Authentication chapter along with dedicated tools for user provisioning provided with LDAP server.

In following subsections we will describe two base LDAP tree shapes along with example LDIFs and portal identity modules configurations. Those two examples differ only by using different MembershipModule implementations and describe only tree shapes with supported user/role creation and removal capabilities.

### 16.4.1. Keeping users membership in role entries

In this example, information about users/roles assignment is stored in roles entries using LDAP "member". Of course any other attribute that comes with schema can be used for this.

Example tree shape in LDAP browser

#### 16.4.1.1. Example LDIF

    dn: dc=example,dc=com
    objectclass: top
    objectclass: dcObject
    objectclass: organization
    dc: example
    o: example

    dn: ou=People,dc=example,dc=com
    objectclass: top
    objectclass: organizationalUnit
    ou: People

    dn: uid=user,ou=People,dc=example,dc=com
    objectclass: top
    objectclass: inetOrgPerson
    objectclass: person
    uid: user
    cn: JBoss Portal user
    sn: user
    userPassword: user
    mail: email@email.com

    dn: uid=admin,ou=People,dc=example,dc=com
    objectclass: top
    objectclass: inetOrgPerson
    objectclass: person
    uid: admin
    cn: JBoss Portal admin
    sn: admin
    userPassword: admin
    mail: email@email.com

    dn: ou=Roles,dc=example,dc=com
    objectclass: top
    objectclass: organizationalUnit
    ou: Roles

    dn: cn=User,ou=Roles,dc=example,dc=com
    objectClass: top
    objectClass: groupOfNames
    cn: User
    description: the JBoss Portal user group
    member: uid=user,ou=People,dc=example,dc=com

    dn: cn=Admin,ou=Roles,dc=example,dc=com
    objectClass: top
    objectClass: groupOfNames
    cn: Echo
    description: the JBoss Portal admin group
    member: uid=admin,ou=People,dc=example,dc=com

#### 16.4.1.2. Example identity configuration

     <modules>
       <module>
          <!--type used to correctly map in IdentityContext registry-->
          <type>User</type>
          <implementation>LDAP</implementation>
          <config/>
       </module>
       <module>
          <type>Role</type>
          <implementation>LDAP</implementation>
          <config/>
       </module>
       <module>
          <type>Membership</type>
          <implementation>LDAP</implementation>
          <config/>
       </module>
       <module>
          <type>UserProfile</type>
          <implementation>DELEGATING</implementation>
          <config>
             <option>
                <name>ldapModuleJNDIName</name>
                <value>java:/portal/LDAPUserProfileModule</value>
             </option>
          </config>
       </module>
       <module>
          <type>DBDelegateUserProfile</type>
          <implementation>DB</implementation>
          <config>
             <option>
                <name>randomSynchronizePassword</name>
                <value>true</value>
             </option>
          </config>
       </module>
       <module>
          <type>LDAPDelegateUserProfile</type>
          <implementation>LDAP</implementation>
          <config/>
       </module>
    </modules>

    <options>
       <option-group>
          <group-name>common</group-name>
          <option>
             <name>userCtxDN</name>
             <value>ou=People,dc=example,dc=com</value>
          </option>
          <option>
             <name>roleCtxDN</name>
             <value>ou=Roles,dc=example,dc=com</value>
          </option>
       </option-group>
       <option-group>
          <group-name>userCreateAttibutes</group-name>
          <option>
             <name>objectClass</name>
             <!--This objectclasses should work with Red Hat Directory-->
             <value>top</value>
             <value>person</value>
             <value>inetOrgPerson</value>
          </option>
          <!--Schema requires those to have initial value-->
          <option>
             <name>cn</name>
             <value>none</value>
          </option>
          <option>
             <name>sn</name>
             <value>none</value>
          </option>
       </option-group>
       <option-group>
          <group-name>roleCreateAttibutes</group-name>
          <!--Schema requires those to have initial value-->
          <option>
             <name>cn</name>
             <value>none</value>
          </option>
          <!--Some directory servers require this attribute to be valid DN-->
          <!--For safety reasons point to the admin user here-->
          <option>
             <name>member</name>
             <value>uid=admin,ou=People,dc=example,dc=com</value>
          </option>
       </option-group>
    </options>

### 16.4.2. Keeping users membership in user entries

In this example, information about users/roles assignment is stored in user entries using LDAP "memberOf". Of course any other attribute that comes with schema can be used for this.

Example tree shape in LDAP browser

#### 16.4.2.1. Example LDIF

    dn: dc=example,dc=com
    objectclass: top
    objectclass: dcObject
    objectclass: organization
    dc: example
    o: example

    dn: o=example2,dc=example,dc=com
    objectclass: top
    objectclass: organization
    o: example2

    dn: ou=People,o=example2,dc=example,dc=com
    objectclass: top
    objectclass: organizationalUnit
    ou: People

    dn: uid=admin,ou=People,o=example2,dc=example,dc=com
    objectclass: top
    objectclass: inetOrgPerson
    objectclass: inetUser
    uid: admin
    cn: JBoss Portal admin
    sn: admin
    userPassword: admin
    mail: email@email.com
    memberOf: cn=Admin,ou=Roles,o=example2,dc=example,dc=com

    dn: uid=user,ou=People,o=example2,dc=example,dc=com
    objectclass: top
    objectclass: inetOrgPerson
    objectclass: inetUser
    uid: user
    cn: JBoss Portal user
    sn: user
    userPassword: user
    mail: email@email.com
    memberOf: cn=User,ou=Roles,o=example2,dc=example,dc=com

    dn: ou=Roles,o=example2,dc=example,dc=com
    objectclass: top
    objectclass: organizationalUnit
    ou: Roles

    dn: cn=User,ou=Roles,o=example2,dc=example,dc=com
    objectClass: top
    objectClass: organizationalRole
    cn: User
    description: the JBoss Portal user group

    dn: cn=Admin,ou=Roles,o=example2,dc=example,dc=com
    objectClass: top
    objectClass: organizationalRole
    cn: Echo
    description: the JBoss Portal admin group

#### 16.4.2.2. Example identity configuration

     <modules>
       <module>
          <!--type used to correctly map in IdentityContext registry-->
          <type>User</type>
          <implementation>LDAP</implementation>
          <config/>
       </module>
       <module>
          <type>Role</type>
          <implementation>LDAP</implementation>
          <config/>
       </module>
       <module>
          <type>Membership</type>
          <implementation>LDAP</implementation>
          <class>org.jboss.portal.identity.ldap.LDAPStaticRoleMembershipModuleImpl</class>
          <config/>
       </module>
       <module>
          <type>UserProfile</type>
          <implementation>DELEGATING</implementation>
          <config>
             <option>
                <name>ldapModuleJNDIName</name>
                <value>java:/portal/LDAPUserProfileModule</value>
             </option>
          </config>
       </module>
       <module>
          <type>DBDelegateUserProfile</type>
          <implementation>DB</implementation>
          <config>
             <option>
                <name>randomSynchronizePassword</name>
                <value>true</value>
             </option>
          </config>
       </module>
       <module>
          <type>LDAPDelegateUserProfile</type>
          <implementation>LDAP</implementation>
          <config/>
       </module>
    </modules>

    <options>
       <option-group>
          <group-name>common</group-name>
          <option>
             <name>userCtxDN</name>
             <value>ou=People,dc=example,dc=com</value>
          </option>
          <option>
             <name>roleCtxDN</name>
             <value>ou=Roles,dc=example,dc=com</value>
          </option>
          <option>
             <name>membershipAttributeID</name>
             <value>memberOf</value>
          </option>
       </option-group>
       <option-group>
          <group-name>userCreateAttibutes</group-name>
          <option>
             <name>objectClass</name>
             <!--This objectclasses should work with Red Hat Directory-->
             <value>top</value>
             <value>person</value>
             <value>inetOrgPerson</value>
          </option>
          <!--Schema requires those to have initial value-->
          <option>
             <name>cn</name>
             <value>none</value>
          </option>
          <option>
             <name>sn</name>
             <value>none</value>
          </option>
       </option-group>
       <option-group>
          <group-name>roleCreateAttibutes</group-name>
          <!--Schema requires those to have initial value-->
          <option>
             <name>cn</name>
             <value>none</value>
          </option>
          <!--Some directory servers require this attribute to be valid DN-->
          <!--For safety reasons point to the admin user here-->
          <option>
             <name>member</name>
             <value>uid=admin,ou=People,dc=example,dc=com</value>
          </option>
       </option-group>
    </options>

## 16.5. Synchronizing LDAP configuration

Like it was described in previous section, you can meet some limitations in identity modules support for more complex LDAP tree shapes. To workaround this you can use identity synchronization on JAAS level. JBoss Portal comes with SynchronizingLoginModule that can be easily configured with other authentication solutions that support JAAS framework. Here we want to provide a simple example on how it can be integrated with LdapExtLoginModule from JBossSX framework.

First of all portal identity modules should be configured to work with portal database - default configuration. This is important as we will leverage them, and we want to synchronize users identity into default portal storage mechanism. So lets look at simple configuration that should take place in jboss-portal.sar/conf/login-config.xml

    <policy>
       <!-- For the JCR CMS -->
       <application-policy name="cms">
          <authentication>
             <login-module code="org.apache.jackrabbit.core.security.SimpleLoginModule"
                           flag="required"/>
          </authentication>
       </application-policy>

       <application-policy name="portal">
          <authentication>

             <login-module code="org.jboss.security.auth.spi.LdapExtLoginModule" flag="required">
                <module-option name="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory
                </module-option>
                <module-option name="java.naming.provider.url">ldap://example.com:10389/
                </module-option>
                <module-option name="java.naming.security.authentication">simple</module-option>
                <module-option name="bindDN">cn=Directory Manager</module-option>
                <module-option name="bindCredential">lolo</module-option>
                <module-option name="baseCtxDN">ou=People,dc=example,dc=com</module-option>
                <module-option name="baseFilter">(uid={0})</module-option>
                <module-option name="rolesCtxDN">ou=Roles,dc=example,dc=com</module-option>
                <module-option name="roleFilter">(member={1})</module-option>
                <module-option name="roleAttributeID">cn</module-option>
                <module-option name="roleRecursion">-1</module-option>
                <module-option name="searchTimeLimit">10000</module-option>
                <module-option name="searchScope">SUBTREE_SCOPE</module-option>
                <module-option name="allowEmptyPasswords">false</module-option>
             </login-module>

             <login-module code="org.jboss.portal.identity.auth.SynchronizingLoginModule"
                           flag="optional">
                <module-option name="synchronizeIdentity">true</module-option>
                <module-option name="synchronizeRoles">true</module-option>
                <module-option name="additionalRole">Authenticated</module-option>
                <module-option name="defaultAssignedRole">User</module-option>
                <module-option name="userModuleJNDIName">java:/portal/UserModule</module-option>
                <module-option name="roleModuleJNDIName">java:/portal/RoleModule</module-option>
                <module-option name="membershipModuleJNDIName">java:/portal/MembershipModule
                </module-option>
                <module-option name="userProfileModuleJNDIName">java:/portal/UserProfileModule
                </module-option>
             </login-module>

          </authentication>
       </application-policy>
    </policy>

Few things are important in this configuration:

- LdapExtLoginModule has flag="required" set which means that if this single LoginModule return fail from authentication request whole process will fail. SynchronizingLoginModule has flag="optional". Such combination is critical as SynchronizingLoginModule always authenticates user sucessfully no matter what credentials were provided. You always must have at least one LoginModule that you will rely on.
- SynchronizingLoginModule is always the last one in whole authentication chain. This is because in commit phase it will take users Subject and its Principals (roles) assigned by previous LoginModules and try to synchronize them. Roles assigned to authenticated user by LoginModules after it won't be handled.

## 16.6. Supported LDAP servers

LDAP servers support depends on few conditions. In most cases they differ in schema support - various objectClass objects are not present by default in server schema. Sometimes it can be workarounded by manually extending schema.

Servers can be

- Supported
- Not Supported
- Experimental - implementation can work with such server but it's not well tested so shouldn't be considered for production.

Table 16.4. Support of identity modules with different LDAP servers

LDAP Server | UserModule | RoleModule | MembershipModule | UserProfileModule
--- | --- | --- | --- | ---
LDAPUserModuleImpl | LDAPExtUserModuleImpl | LDAPRoleModuleImpl | LDAPExtRoleModuleImpl | LDAPStaticGroupMembershipModuleImpl | LDAPStaticRoleMembershipModuleImpl | LDAPUserProfileModuleImpl
Red Hat Directory Server | Supported | Supported | Supported | Supported | Supported | Supported | Supported
OpenDS | Supported | Supported | Supported | Supported | Supported | Not Supported | Supported
OpenLDAP | Supported | Supported | Supported | Supported | Supported | Not Supported | Supported

Prev | Up | Next
Chapter 15. Authentication and Authorization | Home | Chapter 17. Single Sign ON