◂ Back to Profiq blog

Notes on OpenDJ integration with Liferay

Liferay

is a popular open source portal solution written in J2EE technology. It features abundance of portlets and plug-ins, as well as many integration options for popular access management and identity solutions. Unfortunately, OpenDJ is not found anywhere in the official (or extra official) documentation. No need to worry as the set-up is more or less trouble-free.

Web Interface set-up

OpenDJ

, formerly known as

OpenDS

is a full implementation of the LDAP version 3 which is also supported by Liferay as a client. Hence, the integration as a generic LDAP service is rather trivial if performed via Web interface:

  • we need to log in as the administrator and open the _Control Panel_in the _Manage_drop-down menu;
  • we choose the Settings option within the _Portal_section;
  • here, on the left side, under Configuration options, we chose Authentication,_and finally _LDAP;
  • we Add the server;
  • nameparameter identifies this particular server instance;
  • _Other Directory Server_should be selected as a generic LDAP server.

Connection:

  • Base Provider URL represents the server host and port in the URI syntax;
  • Base DN is the starting point in the tree where all the searches should start from;
  • Principalis the user which Liferay uses to connect to the directory and perform required operations;
  • Credentialsis the password of the principal.

Users:

  • Authentication Search Filter is the filter Liferay would use to search for the Liferay users (hoovering over the question mark gives more information on the type of variables that could be used to perform the mapping of Liferay fields to LDAP attributes);
  • Import Search Filter is used to identify the LDAP entries to be imported to Liferay user database, if the import option has been set to true;
  • Screen Nameis the LDAP attribute which will be used for the value of Liferay screen name, by defualt it is “cn” but it could also be “uid”, depending on your directory design;
  • Passwordis the LDAP attribute which holds the user password hash, default is “userPassword” which is also the default value for OpenDJ;
  • E-mail Addressis the LDAP attribute for the e-mail address, by default “mail”;
  • Full Nameis the LDAP attribute for the full name of the user, by default it is empty, but typically it is “cn”;
  • First Nameis the LDAP attribute for the first name of the user, by default it is “givenName”;
  • Middle Nameis the LDAP attribute for the given name, by default it is empty;
  • Last Nameis the LDAP attribute for the last name, by default it is “sn”;
  • Job Titleis the LDAP attribute for the job title, by default it is “title”;
  • Group Membershipis the LDAP attribute which lists the groups which the user belongs to, in OpenDJ this should be set to the operational attribute “isMemberOf”.

Groups:

  • Import Search Filteris the LDAP filter which identifies the entries representing groups to be imported into the Liferay database if the import option has been set to true;
  • Group Nameis the LDAP attribute which holds the name of the group, it defaults to “cn”;
  • Descriptionis the LDAP attribute which holds the description of the group, it defaults to “description”;
  • Useris the LDAP attribute which identifies the LDAP entry belonging to the group, it defaults to “uniqueMember”.

Export:

  • Users DNis the distinguished name of the LDAP branch which holds the user entries;
  • User Default Object Classesrepresents the object class hierarchy for the user entries, it defaults to “top,person,inetOrgPerson,organizationalPerson”;
  • Groups DNis the distinguished name of the LDAP branch which holds the group entries;
  • Group Default Object Classesrepresents the object class hierarchy for the group entries, it defaults to “top,groupOfUniqueNames”.

Most of the default values are reasonable and correspond to the standard schema, so you would normally want to leave them as such. However, apart from the minor changes that might be needed in order to reflect your directory design, the most notable parameter would be the “group membership” which you would want changed to “isMemberOf”.

Properties file setup

Although most of the parameters are configurable through the web interface, there are a few more which can be set only within the

portal-ext.properties

file. Please note that the web interface settings take precedence over the properties file, so if you have the same parameter set in both places, only the one in the web interface would be used.

The properties file has to be created in:

<web server root>/webapps/ROOT/WEB-INF/classes

The LDAP parameters with their default values are:

ldap.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
ldap.base.provider.url=ldap://localhost:10389
ldap.base.dn=dc=example,dc=com
ldap.security.principal=uid=admin,ou=system
ldap.security.credentials=secret
ldap.referral=follow
ldap.auth.enabled=false
ldap.auth.required=false
ldap.auth.method=bind
#ldap.auth.method=password-compare
ldap.auth.password.encryption.algorithm=
ldap.auth.password.encryption.algorithm.types=MD5,SHA
ldap.auth.search.filter=(mail=@email_address@)
ldap.user.default.object.classes=top,person,inetOrgPerson,
organizationalPerson
ldap.user.mappings=uuid=uuidnscreenName=cnnpassword=userPasswordn
emailAddress=mailnfirstName=givenNamenlastName=snnjobTitle=titlen
group=groupMembership
ldap.group.default.object.classes=top,groupOfUniqueNames
ldap.group.mappings=groupName=cnndescription=descriptionn
user=uniqueMember
ldap.import.enabled=false
ldap.import.on.startup=false
ldap.import.interval=10
ldap.import.user.search.filter=(objectClass=inetOrgPerson)
ldap.import.group.search.filter=(objectClass=groupOfUniqueNames)
ldap.import.method=user
#ldap.import.method=group
ldap.import.create.role.per.group=false
ldap.export.enabled=true
ldap.users.dn=ou=users,dc=example,dc=com
ldap.groups.dn=ou=groups,dc=example,dc=com
ldap.password.policy.enabled=false
ldap.error.password.age=age
ldap.error.password.expired=expired
ldap.error.password.history=history
ldap.error.password.not.changeable=not allowed to change
ldap.error.password.syntax=syntax
ldap.error.password.trivial=trivial
ldap.error.user.lockout=retry limit

As you can see, most of the parameters are the same as on the web interface, so we will focus on those that differ and affect the integration with OpenDJ:

  • ldap.auth.method, ldap.auth.password.encryption.algorithmand ldap.auth.password.encryption.algorithm.typesare complementary and define the way Liferay handles authentication: ldap.auth.method_can have two possible values: _bind or password-compare**.**_bind__means the portal would try to perform an LDAP bind operation as the provided user and credentials (looking up it’s DN with what is provided as the _search filter parameter), and password-compare would generate a hash of the provided password and compare it to the has stored in the attribute specified as password_parameter. For the second option, _ldap.auth.password.encryption.algorithm and _type_specify which algorithms to use to produce the hash so that it can be matched to the hash in the directory.
  • ldap.import.methodcan be used to specified the way the LDAP entries are identified for importing (if this feature has been enabled). The possible values are: user_and _group. user_option would use parameters specified for the user discovery (_import filter and the attribute mapping), while the _group_option would first look for the groups and then import all members of the found groups.
  • although ldap.password.policy.enabledparameter exists in the web interface, the parameters which accompany it can be defined only the properties file. This parameter specifies that the Liferay should relay on the directory to handle the password policies (expiration, disabling and such) and the rest of the parameters define portions of the error messages returned by the directory which identify the state the account is in. Those parameters are: **ldap.error.password.age, ldap.error.password.expired, ldap.error.password.history, ldap.error.password.not.changeable, ldap.error.password.syntax, ldap.error.password.trivial, ldap.error.user.lockout.**Although, only ldap.error.user.lockout and ldap.error.password.expiredare relevant as the LDAP authentication module does not verify any other.

LDAP password policy parameters

OpenDJ does not give the reason for the authentication failure by default as a security measure, but this option can be changed:

dsconfig -n -X set-global-configuration-prop –set return-bind-error-messages:true

Possible values might be:

ldap.error.user.lockout=locked
ldap.error.password.not.changeable=password cannot be changed
ldap.error.password.syntax=password validator

The portal would try to match the portions of the message returned by the directory and then act upon it. Note that

ldap.error.password.syntax

and

ldap.error.password.trivial

depend on the particular password validator out you happen to use. All password validators have “password validator” as a common part in the message, but the actual reason differs depending on the particular error. The rest of the parameters are static and some even correspond with the defaults.

OpenDJ Password Policy settings

In order to delegate the use of password policies from the directory to the portal, the directory password policies have to be configured with your custom values:

dsconfig -X -D “cn=directory manager” -w password set-password-policy-prop –policy-name “default password policy”

Hope it helps!

UPDATE:

On the petition of Liferay Community, this article has been added to the Liferay Community Wiki:

http://www.liferay.com/es/community/wiki/-/wiki/Main/LDAP+support+with+OpenDJ

Nemanja Lukic

Written by

Nemanja Lukic

Comments

Leave a Reply

Online comments are not active during the static migration phase.
AI Function Blog Image

Is The Most Valuable AI Function Asking Better Questions?

How the "Grill Me" method became a key part of Project Weaver's approach to AI-assisted software development. We've shared some of the thinking behind Project Weaver—the internal engineering framework we've developed at profiq to help our teams and AI work together more effectively. Rather than treating AI as a magic code generator, Weaver is built around a simple idea: the better the structure, context, and engineering discipline, the better the outcomes.

Posted 4 weeks ago by Anke Corbin

Weaver Prototype Image

From Vibe-Coded Prototype to Production-Ready App Using Weaver

There's an important distinction between a prototype that demonstrates an idea and a system that can support a real business. Recently, we had the opportunity to explore that distinction firsthand while working with Ginger & Nash on an application called c.h.i.p. using profiq Weaver as an AI assistant.

Posted 5 weeks ago by Anke Corbin

Project Weaver Recap

Quick Recap: Project Weaver Engineering Series

We wanted to do another quick recap of the Weaver journey so far for those of you who are just learning about the project, from the first idea through the latest automation and workflow experiments.

Posted 2 months ago by Anke Corbin

Read the Blog