LDAP Integration

eXo Platform organizational entities (users, groups and memberships), can be stored in a database or a directory such as OpenLDAP or Active Directory (AD). This chapter documents how to configure eXo Platform to plug to a directory.


Please notice that this integration is not SSO (Single Sign On). If SSO is what you need, read the SSO chapter, eXo Add-ons guide that explains how eXo Platform works with a directory through an SSO service like CAS or OpenAM.


  • eXo Platform supports only the read-only mode with a directory (LDAP/AD).

  • Only one single directory is allowed.

  • The mapped organizational entities from directory are imported in one way direction: from the directory to eXo Platform.

This chapter covers the following topics:


eXo Platform can be plugged to a directory server to use its users, groups and memberships:

  • the directory can be plugged in read-only mode only

  • the directory can contain users and groups, or only users

  • the supported directory implementations are: OpenLDAP and Microsoft Active Directory. You can refer to our official supported environments matrix for more details about the supported versions.

The term “Directory users” represents users who are created in the directory by its utilities. The term “Platform users” represents users who are created via eXo Platform UI. The understanding is similar for “Directory groups” and “Platform groups”.

Quick Start

eXo Platform provides a set of configuration parameters to define the directory integration. These parameters allow to cover most of the directory types and structures. For more complex or specific directories structures, please refer to the chapter Advanced configuration.

The parameters must be defined in the exo.properties file. The minimal set of parameters to define is:

  • exo.ldap.type - defines the type of directory. Must be ad for Microsoft Active Directory or ldap for any other LDAP directory.

  • exo.ldap.url - defines the URL to connect to the directory.

  • exo.ldap.admin.dn - defines the full DN of the admin user used to fetch data.

  • exo.ldap.admin.password - defines the password of the admin user used to fetch data.

  • exo.ldap.users.base.dn - defines the base DN of the users. Multiple DNs can be provided by separating them by semicolons.

  • exo.ldap.groups.base.dn - (optional, required only if directory groups must be used) defines the base DN of the groups. Multiple DNs can be provided by separating them by semicolons.



The chapter Configuration reference lists all of available parameters. Please refer to this list to check defaults values of these parameters and define them in the exo.properties file to adapt them to your directory characteristics.

Once the parameters are set, the eXo Platform can be started and users and groups will be imported.

Configuration reference

Here is the list of all available configuration properties for directory integration to define in exo.properties:







Type of LDAP server

ldap, ad or empty

Empty (no LDAP/AD integration)



URL to the LDAP/AD server





Full DN of the admin user used to fetch data





Password of the admin user used to fetch data

String String

Empty Empty


Number of milliseconds that a search may last

Any positive number



The maximum results that a search can return

Any positive number

1000 |


Semicolon-separated list of full DNs of the objects containing the users. An empty value means users are not synchronized.




Attribute used to authentified the users

uid for LDAP and sAMAccountName for AD


Attribute used for password for users authentication

userPassword for LDAP and unicodePwd for AD


Filter used to fetch the users


exo.ldap.users.attributes. {firstName|lastName|email}.mapping

Mapping of the mandatory users attributes (firstName, lastName and email)

cn for LDAP and givenName for AD for firstName, sn for lastName and mail for email


Comma-separated list of custom users attributes (for example department,city)



Mapping of the custom user attribute

Name of the custom attribute


Type of the custom user attribute

text or binary



Is the attribute required

true or false



Is the attribute multi-valued

true or false



Scope of the search for users

base, one or subtree



Semicolon-separated list of full DNs of the objects containing the groups. An empty value means groups are not synchronized.

true or false




Attribute used to authenticate the groups



Filter used to fetch the groups



Comma-separated list of custom groups attributes (for example description,city)



Mapping of the custom group attribute

Name of the custom attribute


Mapping of the custom group attribute

Name of the custom attribute


Type of the custom group attribute

text or binary



Is the attribute required

true or false



Is the attribute multi-valued

true or false



Scope of the search for groups

base, one or subtree



LDAP attribute that defines children of IdentityObject. Used to retrieved relationships from IdentityObject entry. Option is required if IdentityObject can be part of relationship.



Defines if values of attribute defined in parentMembershipAttributeName are fully qualified LDAP DNs.

true or false



LDAP attribute that defines parents of IdentityObject. Used to retrieved relationships from IdentityObject entry. Good example of such attribute in LDAP schema is memberOf.

true or false



Defines if values of attribute defined in childMembershipAttributeName are fully qualified LDAP DNs.

true or false



Root group to bind LDAP/AD groups, all LDAP/AD groups will be available under this group. It must end with /. Root group (“/”) cannot be used.

Any group id, ending with /


LDAP/AD connection pool can also be customized in the exo.properties file using JVM standard system properties.

Synchronization configuration

The LDAP integration uses jobs to synchronize periodically the eXo internal database with the data modified in the LDAP. The periodicity of these jobs can be changed in the exo.properties file thanks to the following properties:

# Cron expression used to schedule the job that will import periodically data
# from external store
# (Default value = every ten minutes)
exo.idm.externalStore.import.cronExpression=0 */10 * ? * *
# Cron expression used to schedule the job that will delete periodically data
# from internal store that has been deleted from external store
# (Default value = every day at 23:59 PM)
exo.idm.externalStore.delete.cronExpression=0 59 23 ? * *
# Cron expression used to schedule the job that will process periodically data
# injected in queue
# (Default value = every minute)
exo.idm.externalStore.queue.processing.cronExpression=0 */1 * ? * *
# When users are removed from LDAP/AD or are not retrievable for other reasons (Communication failure, LDAP Filter modified),
# we have two options, either they are removed or they are disabled from the internal store.
# exo.idm.externalStore.entries.missing.delete=true (Default behavior, if value is equal to true users are removed)
# exo.idm.externalStore.entries.missing.delete=false (if value is equal to true users are disabled)

By default, user data are synchronized with the LDAP when he/she signs in. This can be disabled by modifying this property:

# if true, update user data on login time and only when information change
# on external store (Default: true)

The user data sync tasks (one per user) are executed asynchronously via a queue. If a sync task fails, it can be retried. The maximum number of sync retries before the task is abandoned in error can be configured by changing the following property:

# Max retries to process Data synchronization from queue

Advanced configuration

If configuration properties described in the previous chapters are not sufficient, eXo Platform allows to configure directory integration even more finely. eXo Platform uses PicketLink IDM framework that allows a very flexible integration with a directory server. The PicketLink configuration can be directly updated.

The following section is a step-by-step tutorial to integrate eXo Platform with a directory server using Picketink configuration.

If you want to know more about PicketLink IDM configuration, you can refer to the official documentation of PicketLink.

This chapter covers the following topics:

How to map multiple DNs for users?

eXo Platform allows to map users dispatched in multiple directory DNs, like this:


In such case, you should, in addition to previous steps described in the Quick start section, follow these steps:

  1. Open the configuration file picketlink-idm-ldap-config.xml.

  2. Search for the option ctxDNs.

  3. Define the different locations of DNs where your directory users are located:


Since only one type of user can be defined, all users of these DNs must share the same attributes mapping.

How to change default mandatory users attributes mapping?

There are five attributes that should always be mapped (because they are mandatory in eXo Platform):

  • username

  • password

  • firstname

  • lastname

  • email

The username mapping is defined by the option idAttributeName:


The password mapping is defined by the option passwordAttributeName:


The firstname, lastname and email mapping are defined in user attributes:


The default mapping defined in the provided sample configuration files for OpenLDAP and MSAD directories is summarized in the following table:

eXo Platform

Configuration attribute

OpenLDAP default value

MSAD default value


Option idAttributeName




Option passwordAttributeName




Attribute firstName




Attribute lastName




Attribute email



You can update them in the file picketlink-idm-ldap-config.xml to match your specific mapping.

How to map additional user attributes?

As described in the previous section, by default, only 5 attributes are mapped from a directory user to an eXo Platform user. Additional user attributes can be mapped by configuration by adding new attribute element in the attributes section of the USER identity object type. For example if you want to map a directory attribute title to eXo Platform attribute user.jobtitle, you must add this configuration snippet under the “attributes” tag in the file picketlink-idm-ldap-config.xml, as follows:


These attributes can be retrieved in the Portal User Profile with the Java API:

import org.exoplatform.container.ExoContainerContext;
            import org.exoplatform.services.organization.OrganizationService;
            import org.exoplatform.services.organization.User;
            import org.exoplatform.services.organization.UserProfile;

            OrganizationService organizationService = ExoContainerContext.getService(OrganizationService.class);

            String userName = "mary";
            UserProfile userProfile = organizationService.getUserProfileHandler().findUserProfileByName(userName);
            String jobTitle = (String) userProfile.getAttribute("user.jobtitle");

How to map multiple DNs for groups?

As in previous sections, we assume that you already have a populated directory and some groups that should be mapped into eXo Platform.


To be clear about the LDAP “group”, it should be the “groupOfNames” objectClass in OpenLDAP or “group” objectClass in Active Directory. In OpenLDAP (default core.schema), the groupOfNames must have the member attribute.

Under the context DN (ou=Groups,o=acme,dc=example,dc=com), there are several groups as shown in the diagram below:


In this case, you should, in addition to previous steps described in the Quick start section, follow these steps:

  1. Open the configuration file picketlink-idm-ldap-config.xml.

  2. Search for the option ctxDNs to define the multiple locations of DNs where your directory groups are located:


How to map directory groups to a new eXo Platform group?

In the Quick start chapter we map the directory groups to default eXo Platform groups /platform and /organization. In this chapter we will learn how to map directory groups into a new eXo Platform group. Let’s say we want to map the groups contained in the directory DN o=acme,dc=example,dc=com into the eXo Platform group /acme. As a prerequisite, the group /acme must be already created in eXo Platform.

  1. PicketLink configuration

    The first step is to define the mapping configuration in PicketLink configuration file picketlink-idm-ldap-config.xml by adding a new identity object type (we call it acme_groups_type) under the identity store PortalLDAPStore:


    Make sure that the attributes and options are correct, especially:

    • idAttributeName: attribute name to use as the group id.

    • ctxDNs: base DN of the groups in the directory.

    • entrySearchFilter: search expression to filter objects to consider as groups.

    • parentMembershipAttributeName: attribute which holds the list of group members. In OpenLDAP or MSAD default schemas, the member attribute is used, but your schema may use another attribute.

Then this new object type must be referenced in the PortalRepository repository:

  1. eXo configuration

    Besides the PicketLink configuration, the eXo service configuration defined in the file idm-configuration.xml must be updated. A new entry must be added in the fields groupTypeMappings and ignoreMappedMembershipTypeGroupList to map the group defined in PicketLink configuration with the eXo Platform group, as follows:

                         <field name="groupTypeMappings">
                                  <map type="java.util.HashMap">
                         <field name="ignoreMappedMembershipTypeGroupList">
                                 <collection type="java.util.ArrayList" item-type="java.lang.String">

Advanced Configuration reference

This section is a complete description of the available configuration options. It lists the options of both eXo configuration and PicketLink configuration.

eXo configuration

The eXo configuration related to PicketLink integration is defined in these 2 services:

  • org.exoplatform.services.organization.idm.PicketLinkIDMServiceImpl

  • org.exoplatform.services.organization.idm.PicketLinkIDMOrganizationServiceImpl

You can adapt the configuration by updating these services configuration in the file idm-configuration.xml as described in the Quick Start section.

PicketLinkIDMServiceImpl service

This service has the following parameters:

  • config (value-param): location of the PicketLink IDM configuration file.



The “war:” prefix allows to lookup the given location in all deployed webapps.

  • hibernate.properties (properties-param): list of hibernate properties used to create SessionFactory that will be injected in Picketlink IDM configuration registry.

                    <description>Default Hibernate Service</description>
                    <property name="hibernate.hbm2ddl.auto" value="update"/>
                    <property name="hibernate.show_sql" value="false"/>
                    <property name="hibernate.connection.datasource" value="${gatein.idm.datasource.name}${container.name.suffix}"/>
                    <property name="hibernate.connection.autocommit" value="false"/>
                    <property name="hibernate.listeners.envers.autoRegister" value="false"/>
  • hibernate.annotations: list of annotated classes that will be added to Hibernate configuration.

  • hibernate.mappings: list of .xml files that will be added to the hibernate configuration as mapping files.

  • jndiName (value-param): if the ‘config’ parameter is not provided, this parameter will be used to perform the JNDI lookup for IdentitySessionFactory.

  • portalRealm (value-param): the realm name that should be used to obtain the proper IdentitySession. The default value is ‘PortalRealm’.

PicketLinkIDMOrganizationServiceImpl service

This service has the following parameters defined as fields of object-param of type org.exoplatform.services.organization.idm.Config:

  • rootGroupName : the name of the PicketLink IDM Group that will be used as a root parent. The default is GTN_ROOT_GROUP.

  • defaultGroupType: the name of the PicketLink IDM GroupType that will be used to store groups. The default is GTN_GROUP_TYPE.

  • groupTypeMappings : this parameter maps groups added with eXo Platform API as children of a given group ID, and stores them with a given group type name in PicketLink IDM. If the parent ID ends with “/*”, all child groups will have the mapped group type. Otherwise, only direct (first level) children will use this type. This can be leveraged by LDAP if the LDAP DN is configured in PicketLink IDM to only store a specific group type. This will then store the given branch in the eXo Platform group tree, while all other groups will remain in the database.

  • forceMembershipOfMappedTypes: groups stored in PicketLink IDM with a type mapped in ‘groupTypeMappings’ will automatically be members under the mapped parent. The Group relationships linked by the PicketLink IDM group association will not be necessary. This parameter can be set to false if all groups are added via eXo Platform APIs. This may be useful with the LDAP configuration when being set to true, it will make every entry added to LDAP appear in eXo Platform. This, however, is not true for entries added via eXo Platform management UI.

  • ignoreMappedMembershipType: if “associationMembershipType” option is used, and this option is set to true, Membership with MembershipType configured to be stored as PicketLink IDM association will not be stored as PicketLink IDM Role.

  • associationMembershipType : if this option is used, each Membership created with MembrshipType that is equal to the value specified here, will be stored in PicketLink IDM as the simple Group-User association.

  • passwordAsAttribute: this parameter specifies if a password should be stored using the PicketLink IDM Credential object or as a plain attribute. The default value is set to false.

  • useParentIdAsGroupType: this parameter stores the parent ID path as a group type in PicketLink IDM for any IDs not mapped with a specific type in ‘groupTypeMappings’. If this option is set to false, and no mappings are provided under ‘groupTypeMappings’, only one group with the given name can exist in the eXo Platform group tree.

  • pathSeparator: when ‘userParentIdAsGroupType’ is set to true, this value will be used to replace all “/” characters in IDs. The “/” character is not allowed in the group type name in PicketLink IDM.

Frequently asked questions

Q1- How does Directory get ready for integration?

A: Not any condition except that the top DN should be created before being integrated.

You should ensure that the Directory contains an entry like the following:

dn: dc=example,dc=com
objectClass: top
objectClass: domain
dc: example

Q2- How to enable sign-in for LDAP pre-existing users?

A: LDAP users are visible in the Users and Groups Management Page but they are unable to sign in eXo Platform. More exactly, they do not have access permission to any pages.

Additional steps should be done to allow them to sign in:

Q3- How to configure PicketLink to look up users in an entire tree?

A: The default configuration already look up users in an entire tree. This behavior can be modified by updating the properties exo.ldap.users.search.scope in the file exo.properties:


In the case the PicketLink configuration is used, the following option must be used:


See more details at PicketLink IDM configuration.

Q4- Cannot log into eXo Platform: error code 49

A: This may happen with OpenLDAP, when users are created successfully but they cannot login, and there is error code 49 in your LDAP log as follows:

5630e5ba conn=1002 op=0 BIND dn="uid=firstuser,ou=People,o=portal,o=gatein,dc=steinhoff,dc=com" method=128
5630e5ba do_bind: version=3 dn="uid=firstuser,ou=People,o=portal,o=gatein,dc=steinhoff,dc=com" method=128
5630e5ba ==> bdb_bind: dn: uid=firstuser,ou=People,o=portal,o=gatein,dc=steinhoff,dc=com
5630e5ba bdb_dn2entry("uid=firstuser,ou=people,o=portal,o=gatein,dc=steinhoff,dc=com")
5630e5ba => access_allowed: result not in cache (userPassword)
5630e5ba => access_allowed: auth access to "uid=firstuser,ou=People,o=portal,o=gatein,dc=steinhoff,dc=com" "userPassword" requested
5630e5ba => dn: [1]
5630e5ba <= acl_get: done.
5630e5ba => slap_access_allowed: no more rules
5630e5ba => access_allowed: no more rules
5630e5ba send_ldap_result: conn=1002 op=0 p=3
5630e5ba send_ldap_result: err=49 matched="" text=""
5630e5ba send_ldap_response: msgid=1 tag=97 err=49

To resolve this, add an ACL (Access Control List) rule in the slapd.conf file as below:

# Access and Security Restrictions (Most restrictive entries first)
access to attrs=userPassword
        by self write
        ## by dn.sub="ou=admin,dc=domain,dc=example" read ## not mandatory, useful if you need grant a permission to a particular dn
        by anonymous auth
        by users none
access to * by * read