Use cases of configuration to authenticate users with LDAP

Last modified by Thomas Mortagne on 2023/09/04 09:29

Here you can find some detailed uses cases of LDAP authentication configuration:

Active Directory

If you're interested in connecting XWiki with Active Directory you may be interested in the Active Directory Application, which is a paying application dedicated to simplifying the integration of Active Directory with XWiki.

Here are the values of the properties you need to set if your LDAP server implementation is Microsoft Active Directory:

  • ldap_server: name/IP of AD server machine
  • ldap_port: port (e.g. 389)
  • ldap_base_DN: name of root DN (e.g. dc=ad,dc=company,dc=com)
  • ldap_bind_DN: domain\{0} (e.g. ad{0} where {0} will be replaced by username during validation)
  • ldap_bind_pass: {1} (where {1} will be replaced by password during validation)
  • ldap_UID_attr: sAMAccountName
  • ldap_fields_mapping: name=sAMAccountName,last_name=sn,first_name=givenName,fullname=displayName,email=mail,ldap_dn=dn

Example:

xwiki.authentication.ldap.server=adserver
xwiki.authentication.ldap.port=389
xwiki.authentication.ldap.base_DN=dc=subdomain,dc=domain,dc=suffix
xwiki.authentication.ldap.bind_DN=subdomain\\{0}
xwiki.authentication.ldap.bind_pass={1}
xwiki.authentication.ldap.UID_attr=sAMAccountName
xwiki.authentication.ldap.fields_mapping=name=sAMAccountName,last_name=sn,first_name=givenName,fullname=displayName,email=mail,ldap_dn=dn

Apple Open Directory Server

In order to set this up your xwiki.cfg file should have the attributes below set like this:

xwiki.authentication.ldap.bind_DN=uid={0},cn=users,dc=sub,dc=domain,dc=tld
xwiki.authentication.ldap.bind_pass={1}
xwiki.authentication.ldap.UID_attr=uid
xwiki.authentication.ldap.group_classes=apple-group
xwiki.authentication.ldap.group_memberfields=memberUid,uid

Note that if you set it up like this the users logging will need the right to list group members in LDAP server.

Open Directory Server (OpenDS)

Here are the values of the properties you need to set if you would like to authorize only members of a group to log-in. In this case, the group is cn=xwiki,ou=roles,dc=domain,dc=tld

xwiki.authentication.ldap.server=ldap.domain.tld
xwiki.authentication.ldap.port=389

xwiki.authentication.ldap.bind_DN=
xwiki.authentication.ldap.bind_pass=

xwiki.authentication.ldap.base_DN=ou=people,dc=domain,dc=tld
xwiki.authentication.ldap.UID_attr=cn

xwiki.authentication.ldap.group_classes=groupOfNames
xwiki.authentication.ldap.group_memberfields=memberUid
xwiki.authentication.ldap.user_group=cn=xwiki,ou=roles,dc=domain,dc=tld

bind_DN and bind_pass are both empty. The connection to the LDAP server will be anonymous. With OpenDS an anonymous connection can read some needed attributes like userPassword, home, etc.

Generic

I want to have LDAP on subwiki1 but not on subwiki2

Each wiki can have it's own LDAP setup. When LDAP fail on a subwiki it fallback on main wiki.

Two possibilities:

Disable LDAP by default for all wikis and then enable it only in wikis where you want it

Enable LDAP by default for all wikis and then disable it only on wikis where you don't want it

Righs now the authenticator always fallback on main wiki when LDAP is disabled or does not work on subwiki. That mean it's not possible to have LDAP auth working when logging in from main wiki but and failing when logging in from a subwiki. In such a case you will be logged with a global user (main wiki user), same as if you were accessing main wiki and then subwiki in the same session.

But what you can do in this case is to not allow main wiki users from accessing the subwiki which will essentially have the same result.

I want to be able to reuse LDAP users membership in XWiki

E.g. if you want all the LDAP users of the group cn=HMS Lydia,ou=crews,ou=groups,o=sevenSeas to be automatically added in the XWiki group XWiki.XWikiAdminGroup when the user logs in, set:

xwiki.authentication.ldap.group_mapping=XWiki.XWikiAdminGroup=cn=HMS Lydia,ou=crews,ou=groups,o=sevenSeas

If you want to add more mapping add them separated by |:

xwiki.authentication.ldap.group_mapping=XWiki.XWikiAdminGroup=cn=HMS Lydia,ou=crews,ou=groups,o=sevenSeas|\
                                        XWiki.OtherXWikiGroup=HMS Victory,ou=crews,ou=groups,o=sevenSeas

My users are not located in the same organization unit

So you can't use the xwiki.authentication.ldap.bind_DN=cn={0},department=USER,department=INFORMATIK,department=1230,o=MP pattern.

The trick here is to to connect to LDAP with a user able to list LDAP users (and groups if you want to do membership synchronization).

To handle that LDAP authentication automatically searches for the user's DN trying to match the provided login with xwiki.authentication.ldap.UID_attr attribute value. So simply set an existing administrator DN (or any other LDAP user with the right to search in the whole LDAP server) at xwiki.authentication.ldap.bind_DN and its password at xwiki.authentication.ldap.bind_pass. LDAP authentication will use it to connect to the LDAP server, search for the provided user and bind the found DN with the provided password to validate it.

For example if you have an admin user with the DN = "cn=Administrator,dc=mydomain,dc=org" and password "pass" set:

xwiki.authentication.ldap.bind_DN=cn=Administrator,dc=mydomain,dc=org
xwiki.authentication.ldap.bind_pass=pass

My users are not located on the same server

E.g. if you use several subdomains and the users are defined separately in each subdomain. This will likely be the case when you have a configuration like this:

sub1.somedomain.com
sub2.somedomain.com
sub3.somedomain.com
...

Approach 1: Let the user indicate the domain

Since 9.0 it's possible to map a different configuration for each in the xwiki.cfg file by playing with the xwiki.authentication.ldap.remoteUser* properties.

Then instead of typing myuid the user will login using something like myuid@MYDOMAIN so that the LDAP authenticator kind find the right server setup based on the provided domain.

Approach 2: Configure group membership login

One possible solution is to make one (or more) group(s) in your AD and set the group membership to all users that have to have access to your wiki. Then configure XWiki to only let members of that group log in. If a user wants to log in, XWiki will look up if the user's credentials are found in the group member attributes in AD. With this setting, XWiki will ignore the base_DN search, if a user was found in that group.

The group membership attribute in AD (in its default configuration) will contain the CN ("FirstName LastName") - not the sAMAccountName. So your users will have to login with their full name instead of their username.

I'm in a multiwiki environment and I want my LDAP users to register only on the main wiki

Each wiki can have its own LDAP configuration (even enable/disable LDAP) in the XWiki.XWikiPreference page or using the LDAP Application. What you can find in the xwiki.cfg configuration file is just the default LDAP configuration and it can be overridden in subwikis.

When the LDAP authenticator fails to authenticate to a wiki it will try in the main wiki.

In order to forbid LDAP authentication to create users on subwikis you can use one of the following ways:

  • disable LDAP in xwiki.cfg and enable it in the main wiki by choosing "Yes" for the "LDAP" field
  • enable LDAP in xwiki.cfg and disable it in every sub-wikis that are not allowed to create users by choosing "No" in the "LDAP" 

I want to allow access to users depending on a specific attribute on their LDAP entry

For example, suppose you want to prevent access to the wiki for deactivated users, and you have an attribute in LDAP showing the current status of the user.

Typically, you may have this kind of attribute:

  • For Zimbra based LDAP, an active account has this attribute: zimbraAccountStatus=active
  • For ActiveDirectory, a deactivated account has this attribute: userAccountControl:1.2.840.113556.1.4.803:=2
  • Or you can have your own attribute in your private schema, for example: accountstatus=active

In this case, you just have to modify the xwiki.authentication.ldap.user_group value by putting the filter corresponding to what you want. Using the same example as above, you'll have:

  • For Zimbra based LDAP:
    xwiki.authentication.ldap.user_group=(zimbraAccountStatus=active)
  • For ActiveDirectory:
    xwiki.authentication.ldap.user_group=(!(userAccountControl:1.2.840.113556.1.4.803:=2))
  • For a private attribute:
    xwiki.authentication.ldap.user_group=(accountstatus=active)

You can of course use any kind of filter. For instance, you can check if the account is active and has any other attribute, like an attribute listing the different services the user can access:

xwiki.authentication.ldap.user_group=(&(accountstatus=active)(allowedservice=xwiki))

Use LDAP over SSL (ldaps authentication)

To adds support for SSL connections to the ldap server you need:

  • to set (xwiki.authentication.ldap.ssl) parameter in xwiki.cfg
    #-# SSL connection to LDAP server
    #-# - 0: normal
    #-# - 1: SSL
    #-# The default is 0
    xwiki.authentication.ldap.ssl=1
  • and add to the trust store of the JSSE extension the CA certificate which delivered the SSL certificate of the ldap server.

    From the Sun JSSE documentation: The search order for the locating the trust store is:

    1. <java-home>/lib/security/jssecacerts, then
    2. <java-home>/lib/security/cacerts
      If the file jssecacerts exists, then cacerts is not consulted. So in order to make it work you have to create a trust store named jssecacerts with the following command and place it in the suitable directory of the JRE or JDK used by your container:
      keytool -import -trustcacerts -alias ca -file cacert.crt -keystore jssecacerts
      (answer yes when asked if you want to trust the certificate). I read on the web the default password for cacerts is 'changeit' so I used that, I didn't try yet with another password for the trust store.
      Since xwiki 8.3, the default extension repositories use httpS and if the file jssecacerts already exists (ie for ldapS in xwiki previous version) then cacerts is not consulted and extension update (and probably install too) display an error: unable to find valid certification path to requested target.
      The problem is:
    • cacerts containing all certificate/keys (and the one for httpS extension repositories)
    • jssecacerts containing only ldapS certificate
      Then, to use ldapS and extension update, you must import ldapS certicate in existent cacerts file instead to create a new one (and rename it in jssecacerts to not forget it)

      cp <java-home>/lib/security/cacerts <java-home>/jre/lib/security/cacerts.ori
      <java-home>/bin/keytool -import -trustcacerts -alias ca -file /my/path/ToLdapS/cert/MyLdapCertificate.pem -keystore <java-home>/lib/security/cacerts
      mv <java-home>/lib/security/cacerts <java-home>/lib/security/jssecacerts
      mv <java-home>/lib/security/cacerts.ori <java-home>/jre/lib/security/cacerts

Get Connected