Introduction
The purpose of this post is to explain the CloverDX Server LDAP configuration and to provide necessary guidance and some how-to's to learn LDAP and CloverDX Server integration. By going through this guide, you will be able to centralize your CloverDX Server user management into your LDAP/Active Directory.
LDAP is a powerful, standardized concept of organizing information. With that often comes a few major trade-offs:
- It's highly complex for beginners
- There are vendor specific differences against standard
- Error messages can be cryptical
Connecting to LDAP
Before configuring the CloverDX Server to work with LDAP, you should have a basic understanding of how LDAP works. If you're familiar with it already, you can skip to the next chapter.
For basic information about LDAP, please read this Wikipedia article. You may actually want to jump there right now and read the article there before continuing this one.
You also need an LDAP server instance. It makes sense to first check the installation by logging into your OS, mail account, etc. It can also be helpful to visualize your LDAP structure so you can get a better idea about what you're doing. If your LDAP server provider does not have a good tool for that, you can try JXplorer. It's free and simple to use. Talk to your system administrator to get a better understanding of your LDAP setup.
Distinguished Names (DN)
LDAP is based on storing objects in its database. These objects are referred to by their Distinguished Names (DN). Basically it's a record of path through LDAP tree. A sample of such DN can be: cn=John Doe,ou=people,dc=MyCompany,dc=com
To reach such an object you need to drill down in reverse order like this:
- find an object with attribute "dc" with value "com" in the root of LDAP directory
- among its children nodes, find one with attribute "dc" set to "MyCompany"
- among its children nodes, find one with attribute "ou" set to "people"
- among its children nodes, find one with attribute "cn" set to "John Doe", that is it!
Here is an example object with its attributes:
cn=John Doe,ou=people,dc=MyCompany,dc=com |
cn |
John Doe |
objectClass |
organizationalPerson |
sn |
Doe |
uid |
doej |
displayName |
John Doe |
givenName |
John |
mail |
johndoe@mycompany.com |
LDAP search filter
The LDAP search filter is an expression used for search in LDAP tree. You can run such expression in JXplorer by Search->Search dialog. Fill Start Searching From with start node (called base in Server) and fill Text Filter. You can see the usage in the following images.
An example of user search:
An example of groups assigned to user search:
When a search is successful, you should see found nodes in the left tab "Results". Click on it to see the object (select simple or text mode of HTML View).
LDAP authentication workflow in the CloverDX Server
The following steps describe how CloverDX Server and LDAP work together:
- The user fills the username and password into the login form and submits it; the Server checks the user type: either local (managed by the Server) or LDAP (this is what we'll set up). Assume the user type is LDAP;
- The Server tries to connect to the configured LDAP server;
- If the connection is successful, the Server tries to find user by username (see below);
- If the user is found, the Server tries to list groups assigned to this user
- The Server tries to match the user's LDAP groups to Server groups; i.e., all groups that are defined in the Server are intersected with user's LDAP groups. All other are ignored. Thus, LDAP groups identify Server user groups which define user's permissions;
- The user might need to be a member of an allowed group (see security.ldap.allowed_ldap_groups below);
- The password is checked against LDAP;
- User is logged in if password is correct and has at least one group assigned.
CloverDX Server LDAP settings
Let's take a look at what you need to do in the Server configuration to enable LDAP authentication. For details on Server settings, please refer to this page in the documentation. It's important to restart your application server after each change of configuration to apply it.
First, locate the clover.xml configuration. For example, on Tomcat server, each setting mentioned below would be written to [tomcat]\conf\Catalina\localhost\clover.xml file. Refer to the documentation to find the file in your installation.
A sample LDAP configuration in clover.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/clover" crossContext="true">
<Manager pathname=""/>
<Parameter name="security.authentication.allowed_domains" value="clover,LDAP" override="false" />
<Parameter name="security.ldap.url" value="ldap://mail.mycompany.com:389" override="false" />
<Parameter name="security.ldap.user_search.base" value="ou=people,dc=MyCompany,dc=com" override="false" />
<Parameter name="security.ldap.user_search.filter" value="(uid=${username})" override="false" />
...
</Context>
In the XML above, you can see the Parameter tags. The following chapter will describe all LDAP-related parameters you can use in your configuration.
In case you encounter errors in any of the steps below, check your logs. You can read more about the Server logs location here. Interesting files are (for Tomcat):
- [tomcat]\temp\cloverlogs\userAction.log - contains log of user actions and their results (login succeed/failed)
- [tomcat]\temp\cloverlogs\all.log - contains more technical information
Enable LDAP log in (workflow - step 1)
security.authentication.allowed_domains
Enabled authentication methods. Can be either clover or LDAP or both separated by a comma (i.e. clover,LDAP).
Test correct settings
You should now be able to create a user with domain set to LDAP. Let's create a new user doej for further testing.
Connection to LDAP server (workflow - step 2)
security.ldap.ctx_factory
The class name with namespace containing context provider implementations. Use "com.sun.jndi.ldap.LdapCtxFactory" for start.
security.ldap.timeout
Timeout when accessing your LDAP server. Use "5000" (unit is milliseconds) for start.
security.ldap.records_limit
Limit of records number returned by the server. Use "50" for start.
security.ldap.url
The URL of your server including port; in format ldap://hostname:port
. The default port of the LDAP is 389, or 636 for SSL connection. For Microsoft Active Directory specifics, please see paragraph in the "Pitfalls" section. You can check your URL using JXplorer.
security.ldap.userDN
security.ldap.password
If your LDAP server requires authentication, fill in the credentials of the user who will perform the queries. It's recommended that you create a dedicated user with minimal rights sufficient for this purpose. You can test the credentials by logging in via JXplorer to your LDAP server. "userDN" is the abbreviation for User Distinguishable Name.
Test correct settings
Try to log in to the CloverDX Server user with the newly created user ('doej' in our example). If the settings were incorrect, then "Login failed" will appear with a message similar to one of these:
- my.domainX.com:3893 (server was not found)
- my.domain.com:38931; socket closed (cannot open connection to found server)
- ...or another connection-related message
Use JXplorer and experiment to get working settings.
User lookup (workflow - step 3)
security.ldap.user_search.base
This property describes the DN of a node where the search for user object starts. Use the topmost node which contains all required users (as subnodes). For our example mentioned above, you would use "ou=people,dc=MyCompany,dc=com".
security.ldap.user_search.scope
This setting specifies the behavior of your search:
- SUBTREE - search recursively all child nodes of
security.ldap.user_search.base
- ONELEVEL - search just immediate child nodes of
security.ldap.user_search.base
- OBJECT - the object is selected directly, i.e. only
security.ldap.user_search.base
node is checked
security.ldap.user_search.filter
The filter to find proper object. The value can be something like (uid=${username})
, where ${username}
is substituted by the login that was typed into the login form, uid
is the name of LDAP attribute which should match against the user's login.
Test correct settings
Again, you can test this filter in your LDAP tool. See the LDAP search filter section. Just replace "${username}" with the user login. For example, (uid=doej)
should find our user. Do not forget to set the correct start point for your search (see security.ldap.user_search.base).
It should also be possible to log into the Server already, but the user will not have any group assigned yet.
Groups assigned to User lookup (workflow - step 4)
security.ldap.groups_search.base
This property describes the DN of a node where the search for group objects starts. Use the topmost node which contains all required groups (as subnodes). For our example, ou=groups,dc=MyCompany,dc=com
.
security.ldap.groups_search.filter
This filter should return all group objects for the user found in step 3 where this user is a member. For example, (&(objectClass=group)(member=${userDN}))
. This search returns all objects of class "group" which contain attribute "member" set to the user's DN. (${userDN}
is replaced with the DN of the user object from step 3. You may want to change this query if your class or attribute names differ.
security.ldap.groups_search.scope
Same as security.ldap.user_search.scope
.
Test correct settings
You can test this filter in your LDAP tool. See LDAP search filter section. Just replace "${userDN}" by some user DN. For example, (&(objectClass=group)(cn=John Doe,ou=people,dc=MyCompany,dc=com))
should find our user. Do not forget to set the correct start point for your search (see security.ldap.user_search.base).
Group binding (workflow - steps 5 and 6)
security.ldap.groups_search.attribute.group_code
Once groups are found, each value of an attribute given by this setting is extracted. For example a value "cn" and its value "my_test_group", when extracted, are matched against the Server groups field "code". In our example, the "code" field of the Server group must be set to "my_test_group" to be matched. The user gets a membership assigned in all matched groups.
security.ldap.allowed_ldap_groups
This field may contain a list of group DNs which the user must be a member of to be able to log in.
For example, cn=test1,ou=groups,dc=MyCompany,dc=com;cn=test2,ou=groups,dc=MyCompany,dc=com
will allow access only to users with membership in "test1" and "test2".
Can be set to _ANY_
which turns off this feature and allows any LDAP user to log in.
Test correct settings
Now you should be able to log in to the CloverDX Server and be assigned proper groups based on your LDAP groups
Pitfalls
SSL access
For the CloverDX Server running in an application server, the SSH setting is fully transparent and managed on the application server level. Please follow the instructions for your application server.
Here are some useful tips:
- Add a server certificate to Java default truststore. See here (section "Importing Certificates")
- Create your own trust store and replace the Java default trust store via a system property
You also need to set the system property com.sun.jndi.ldap.connect.pool.protocol=ssl
in a place where you normally set other system properties (e.g. in "[tomcat]/bin/catalina.sh" add to "CATALINA_OPTS" -Dcom.sun.jndi.ldap.connect.pool.protocol=ssl
). Please note that this will not work if set in environment variables. In the end, you should have:
-Djavax.net.ssl.trustStore=keystore.ks
(if you have your own trust store)
-Djavax.net.ssl.trustStorePassword=MY_PASSWORD
(if you have your own trust store)
-Dcom.sun.jndi.ldap.connect.pool.protocol=ssl
-Djavax.net.debug=true
(recommended for setup phase)
Microsoft Active Directory (AD) - Global Catalog and Referrals
If your Microsoft AD is using "referrals," you can be getting a message like Unprocessed Continuation Reference(s); remaining name 'DC=ad,DC=mycompany,DC=org'
in the CloverDX Server log. Referrals is a technique of linking information scattered across the LDAP directory into one node. See LDAP Referrals for details. For example, when users in your LDAP directory are placed in multiple locations, you are able to virtually aggregate them into a single location by using referrals. By default, Microsoft AD is running services on these ports:
- 389 - the default LDAP port; you can use this if you don't have referrals
- 3268 - global catalog port which is able to follow referrals. See What Is the Global Catalog? for details.
Thus, if you suffer the error mentioned above, it may help to change the Server setting security.ldap.url
to use the global catalog. So for example:security.ldap.url=ldap://my.domain:3268
Known issues
All versions of the Clover Server prior to 3.3.0-M3 contain bugs reported in issue CLS-735. This means that when attribute values used for DNs contain a comma "," character, the login fails. When "cn" in the example above is changed to "John, Doe" then it's incorrect and will cause problems during the log in process. This is important mainly for DN used in the "member" attribute of "group" object.