This page last changed on Apr 21, 2010 by rhartono.

In this document::

Prerequisites

Before reading this, ensure you understand the configuration details outlined in Customising atlassian-user.xml. This describes how to configure a single LDAP repository in Confluence, and is prerequisite knowledge for following the instructions below.

For brevity, all examples on this page are partial examples. A complete atlassian-user.xml LDAP configuration can be found in Customising atlassian-user.xml.

You will need at least Confluence 2.3 or higher to be able to use these instructions.

Configuration

To configure multiple LDAP repositories in Confluence, put multiple <ldap>...</ldap> entries into confluence/WEB-INF/classes/atlassian-user.xml.

The order of the entries in the file will be the order that the repositories are searched for users. That is, if a user tries to log in with the username jsmith, the first repository in atlassian-user.xml will be searched for the user with the username jsmith. If no user is found in that repository, the second repository specified in atlassian-user.xml will be searched.

Here is a partial configuration that connects Confluence to two different LDAP servers. They are given the identifiers ldap1 and ldap2, and connect to the servers ldap-sf.example.org and ldap-nyc.example.org respectively.

If you change your ldap key to a different name, you will need to change the cache name to pick it up. This is described in CONFKB181536872.
<atlassian-user>
    <repositories>
        <ldap key="ldap1" name="San Francisco Example Repository" cache="true">
            <host>ldap-sf.example.org</host>
            <port>389</port>
    
            <!-- ... remainder of server configuration ... -->

        </ldap>

        <ldap key="ldap2" name="New York City Example Repository" cache="true">
            <host>ldap-nyc.example.org</host>
            <port>389</port>
   
            <!-- ... remainder of server configuration ... -->

        </ldap>

        <hibernate key="hibernate" name="Hibernate Repository" description="Hibernate Repository" />
    </repositories>
</atlassian-user>

Points to note:

  • each server must have a unique key attribute
  • each server must include the full LDAP configuration, including baseUserNamespace, baseGroupNamespace and so on
  • Confluence's internal repository, the <hibernate> repository, must be specified last
  • you can include more than two LDAP repositories, but please read the Side effects section below.

Side effects

The main side effect of configuring multiple LDAP servers is degrading performance. There are many activities in Confluence where user or group information is retrieved:

  • logging in
  • user/group searches
  • permission checks when viewing or editing a page.

Confluence tries to cache as much information as possible from the LDAP queries, but almost certainly adding multiple LDAP servers will degrade the performance of the application. This is especially true if any of the LDAP servers are geographically distant from Confluence, where any LDAP query has a significant latency (> 50 ms roundtrip).

Cache configuration

Clustered Edition

You will need to configure your <Confluence-Home-Directory>/config/confluence-coherence-cache-config.xml or <Confluence-Home-Directory>/config/confluence-coherence-cache-config-clustered.xml file to add LDAP related caches for every additional LDAP repository being added to atlassian-user.xml.

To do this, please add the following block of lines to respective cache configuration file, for each additional LDAP repository being configured:

 <!-- second LDAP repository -->
        <cache-mapping>
            <cache-name>com.atlassian.user.impl.hibernate.HibernateUserManager.ldapRepository2.users</cache-name>
            <scheme-name>user</scheme-name>
        </cache-mapping>

        <cache-mapping>
            <cache-name>com.atlassian.user.impl.hibernate.HibernateUserManager.ldapRepository2.groups_getGroupsForUser</cache-name>
            <scheme-name>user</scheme-name>
        </cache-mapping>
        
        <cache-mapping>
            <cache-name>com.atlassian.user.impl.ldap.LDAPUserManagerReadOnly.ldapRepository2.users</cache-name>
            <scheme-name>user</scheme-name>
        </cache-mapping>
		
        <cache-mapping>
            <cache-name>com.atlassian.user.impl.ldap.LDAPUserManagerReadOnly.ldapRepository2.users_ro</cache-name>
            <scheme-name>user</scheme-name>
        </cache-mapping>
        <cache-mapping>
            <cache-name>com.atlassian.user.impl.ldap.LDAPUserManagerReadOnly.ldapRepository2.repository</cache-name>
            <scheme-name>user</scheme-name>
        </cache-mapping>

        <cache-mapping>
            <cache-name>com.atlassian.user.impl.ldap.LDAPGroupManagerReadOnly.ldapRepository2.groups</cache-name>
            <scheme-name>user</scheme-name>
        </cache-mapping>
        <cache-mapping>
            <cache-name>com.atlassian.user.impl.ldap.LDAPGroupManagerReadOnly.ldapRepository2.groups_hasMembership</cache-name>
            <scheme-name>user</scheme-name>
        </cache-mapping>
        <cache-mapping>
            <cache-name>com.atlassian.user.impl.ldap.LDAPGroupManagerReadOnly.ldapRepository2.groups_getGroupsForUser</cache-name>
            <scheme-name>user</scheme-name>
        </cache-mapping>
        <cache-mapping>
            <cache-name>com.atlassian.user.impl.ldap.LDAPGroupManagerReadOnly.ldapRepository2.repositories</cache-name>
            <scheme-name>user</scheme-name>
        </cache-mapping>
       
        <!-- END second LDAP Repository -->
Standard Edition

If you are using a Standard Edition of Confluence, please implement the LDAP configurations below into your <Confluence-Home-Directory>/config/ehcache.xml file:

<!-- --><cache name="com.atlassian.user.impl.ldap.HibernateUserManager.ldapRepository2.users" maxElementsInMemory="5000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="0" overflowToDisk="false" />
<!-- --><cache name="com.atlassian.user.impl.ldap.HibernateUserManager.ldapRepository2.groups_getGroupsForUser" maxElementsInMemory="5000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="0" overflowToDisk="false" />

<!-- --><cache name="com.atlassian.user.impl.ldap.LDAPGroupManagerReadOnly.ldapRepository2.groups" maxElementsInMemory="5000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="0" overflowToDisk="false" />
<!-- --><cache name="com.atlassian.user.impl.ldap.LDAPGroupManagerReadOnly.ldapRepository2.groups_getGroupsForUser" maxElementsInMemory="5000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="0" overflowToDisk="false" />
!-- --><cache name="com.atlassian.user.impl.ldap.LDAPGroupManagerReadOnly.ldapRepository2.groups_hasMembership" maxElementsInMemory="5000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="0" overflowToDisk="false" />
<!-- --><cache name="com.atlassian.user.impl.ldap.LDAPGroupManagerReadOnly.ldapRepository2.repositories" maxElementsInMemory="5000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="0" overflowToDisk="false" />
<!-- --><cache name="com.atlassian.user.impl.ldap.LDAPUserManagerReadOnly.ldapRepository2.users" maxElementsInMemory="5000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="0" overflowToDisk="false" />
<!-- --><cache name="com.atlassian.user.impl.ldap.LDAPUserManagerReadOnly.ldapRepository2.groups_getGroupsForUser" maxElementsInMemory="5000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="0" overflowToDisk="false" />
<!-- --><cache name="com.atlassian.user.impl.ldap.LDAPUserManagerReadOnly.ldapRepository2.repository" maxElementsInMemory="5000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="0" overflowToDisk="false" />
<!-- --><cache name="com.atlassian.user.impl.ldap.LDAPUserManagerReadOnly.ldapRepository2.users_ro" maxElementsInMemory="5000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="0" overflowToDisk="false" />

Please replace the example LDAP key above ldapRepository2, with your relevant LDAP key, such that it matches the one defined in your atlassian-user.xml file.

Two connections to the same server

It also possible, but not usually recommended, for Confluence to connect twice to the same server. When connecting twice to the same server, you must not have overlapping group or user namespaces in the LDAP tree.

Here is an partial configuration, retrieving two separate LDAP user branches, but only one LDAP group branch. To configure only a single group branch, the group filter in the second LDAP repository searches for a non-existent value so it will not return any results. (This is generally fast as long as your LDAP server has an index on objectClass for the given tree section.)

<atlassian-user>
    <repositories>
        <ldap key="ldap1" name="Example Repository, SF user tree" cache="true">
            <host>ldap.example.org</host>
            <port>389</port>
            <!-- ... remainder of connection configuration ... -->
        
            <!-- user search filter -->
            <baseUserNamespace>cn=San Francisco,dc=ldap,dc=example,dc=org</baseUserNamespace>
            <userSearchFilter>(objectClass=user)</userSearchFilter>
        
            <!-- ... remainder of user configuration ... -->
        
            <!-- group search filter -->
            <baseGroupNamespace>cn=Groups,dc=ldap,dc=example,dc=org</baseGroupNamespace>
            <groupSearchFilter>(objectClass=group)</groupSearchFilter>
        
            <!-- ... remainder of server configuration ... -->
        </ldap>
        <ldap key="ldap2" name="Example Repository, NYC user tree" cache="true">
            <host>ldap.example.org</host>
            <port>389</port>
            <!-- ... remainder of connection configuration ... -->
        
            <!-- user search filter -->
            <baseUserNamespace>cn=New York City,dc=ldap,dc=example,dc=org</baseUserNamespace>
            <userSearchFilter>(objectClass=user)</userSearchFilter>
        
            <!-- ... remainder of user configuration ... -->
        
            <!-- group search filter -->
            <baseGroupNamespace>cn=Groups,dc=ldap,dc=example,dc=org</baseGroupNamespace>
            <groupSearchFilter>(objectClass=nothing)</groupSearchFilter>
        
            <!-- ... remainder of server configuration ... -->
        </ldap>
        <hibernate key="hibernate" name="Hibernate Repository" description="Hibernate Repository" />
    </repositories>
</atlassian-user>

Points to note:

  • each repository will have its own connection pool, so Confluence will use twice as many connections to the LDAP server
  • performance will typically be degraded, as discussed in Side effects above
  • each server must have a unique key attribute
  • each server must include the full LDAP configuration, including baseUserNamespace, baseGroupNamespace and so on
  • Confluence's internal repository, the <hibernate> repository, must be specified last.

Single Sign-On Alternative

Rather than configuring multiple LDAP repositories, you're able to reduce the overhead of having multiple LDAP servers by setting up an SSO solution as an intermediate user manager. Confluence only needs to lookup the SSO tool once, and that tool then looks up both servers on behalf of Confluence. The SSO tool essentially federates your LDAP servers into a single service and also caches the results across all applications that use single sign-on.

The main advantage is that if a user is already logged into any applications that have single sign-on enabled, then their account details will already be cached by the SSO tool and can normally be served from cache. Only the first application request needs to wait for the LDAP response, with subsequent requests from that or other applications able to use the SSO cache until it expires. If your LDAP servers are high-latency, then you can also reduce latency on cache lookups by locating the SSO tool closer to your Confluence server. Atlassian Crowd is an example SSO solution that already integrates with LDAP and all Atlassian tools.

Related pages

Customising atlassian-user.xml
Add LDAP Integration

Document generated by Confluence on Jul 09, 2010 01:09