2017-01-03

Liferay 6.1 - connecting to LDAP server

I've been working on a portal project recently using Liferay.  After getting Liferay installed on a local VM I was tasked with connecting it to an LDAP server for user authentication and importing groups for permissions.

Adding an LDAP server is simple.  Liferay has buttons for testing the connection, user import (with preview) and group import (with preview) that are extremely helpful.  Obviously, all of your settings will depend on the LDAP server you're connecting to.  In my case I didn't need to change any of the user and group default settings.  I did have to change the defaults for the connection.

I  found that using the Liferay control panel was the best way to connect to the LDAP server and determine the settings you need.  What you do with the settings after that really depends on your situation.  I'm a developer, and the project required extensive Liferay customizations.  Therefore, I moved the settings into an Ext plugin which we managed in SVN and deployed to multiple environments.  Alternatively, each environment can be manually however you may find this to be difficult to manage.
I wanted my own LDAP server because I needed to create my own set of users, groups, and have complete control over the structure.
I installed openLDAP locally and connected to it using jxplorer.  Then I created a bunch of groups and users by importing an ldif file.  My database looked good, and connecting/navigating it using jxplorer worked fine.  
To help verify/debug connecting to LDAP servers I used jxplorer, which is free and available for all of the common OSs.
 
The Technical Details

In my case the LDAP server is a test server, and was really easy to connect.  The hardest part was finding where the LDAP settings are located in the Liferay control panel. To get to the LDAP settings:
  1. Login to Liferay (http://localhost:8080, in my case test@liferay.com:test)
  2. Navigate to the control panel (Go To->Control Panel)
  3. Then under Portal in the left navigation, go to Authentication->LDAP

The options for LDAP are pretty self-explanatory:
  • Enabled - enable LDAP authentication
  • Required - require LDAP authentication (the only exception I'm aware of is the default admin user created when first logging into Liferay)
  • Import Enabled - import LDAP users and groups into Liferay
  • Export Enabled - export user and group changes made in Liferay to LDAP
  • Use LDAP Password Policy - I recommend selecting this, otherwise when users first login they will be forced to change their password
There are some useful LDAP options (for Liferay 6.1) that you can add to your portal-ext.properties file as well.  In my case I'm using the glassfish hosted version of Liferay 6.1, so my portal-ext.properties file is in liferay-portal-6.1.20-ee-ga2/glassfish-3.1.2/domains/domain1/applications/liferay-portal/WEB-INF/classes.  The following are some of the more useful settings that I used.
  • ldap.import.on.startup=false
  • ldap.import.interval=10
  • ldap.import.create.role.per.group = true
    • This is to create a role for each group, and add each group member to that role
    • I use this because all our permissions are role based
  • ldap.import.enabled=true
  • ldap.export.enabled=true
  • ldap.import.method=group
    • Only import users that are part of groups
    • The other option is user, i.e. only import groups that have users

In my case I needed to fill out my Base DN to import the users (dc=example,dc=com).
  •  Connection
    • Base Provider URL - ldap://192.168.1.55:389
    • Base DN - dc=example,dc=com
    • Principal - cn=Manager,dc=example,dc=com
    • Credentials - *****
  • Users
    • All defaults
  • Groups
    • All defaults
  • Export
    • Users DN - dc=example,dc=com
    • User Default Object Classes - top,inetOrgPerson,person
    • Groups DN - dc=example,dc=com
    • Group Default Object Classes - top,groupOfUniqueNames

Minor Issues I Encountered

The first issue you might run into is a certificate problem (if using ldaps).  Logging in will simply fail, and there won't be anything in the logs either.  To fix the problem you have to add the LDAP certificate to the Java cacerts store.

Then, Liferay could only connect.  Trying to import users and groups failed.  Eventually I determined that the problem was because I hadn't added the user I use to login to LDAP to the LDAP database.  I'm not sure why Liferay requires this and jxplorer doesn't, or for that matter why the user isn't automatically added to the database during installation/setup, but it's not.

During the import I ran into an problem.  I had issues (debugged continually restarting Liferay and using the liferay log file which was very time consuming) with screen names.  I simplified all my users so that they only contain alpha-numeric characters for all properties (cn, sn, uid, etc...).

Another possible issue you may run into is how LDAP is storing passwords.  By default Liferay seems to expect plain text, so that's what I'm using on my LDAP server.  Obviously you don't want to do this in production.  However, during development plain text is fine.

LDIF Snippet for Generating Users

Here's a snippet of the LDIF file I imported to setup my users and groups (LDIF->Import file in jxplorer):


dn: cn=u1,ou=users,dc=example,dc=com
cn: u1
sn: u1
objectClass: top
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
uid: u1
ou: users
givenName: u1
title: Mr.
mail: u1@
liferay.com
userpassword: u1

dn: cn=u2,ou=users,dc=example,dc=com
cn: u2
sn: u2
objectClass: top
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
uid: u2
ou: users
givenName: u2
title: Mr.
mail: u2@
liferay.com
userpassword: u2

dn: cn=u3,ou=users,dc=example,dc=com
cn: u3
sn: u3
objectClass: top
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
uid: u3
ou: users
givenName: u3
title: Mr.
mail: u3@liferay.com
userpassword: u3



dn: cn=g1,ou=Groups,dc=example,dc=com
objectClass: top
objectClass: groupOfUniqueNames
cn: g1
description: g1
uniquemember: cn=u1,ou=users,dc=example,dc=com
ou: groups

dn: cn=g2,ou=Groups,dc=example,dc=com
objectClass: top
objectClass: groupOfUniqueNames
cn: g2
description: g2
uniquemember: cn=u2,ou=users,dc=example,dc=com
ou: groups

dn: cn=g3,ou=Groups,dc=example,dc=com
objectClass: top
objectClass: groupOfUniqueNames
cn: g3
description: g3
uniquemember: cn=u3,ou=users,dc=example,dc=com
ou: groups