Skip to main content
07 Aug 2012

 

Context 

“Bringing” users from an external Active Directory server or any other directory server supporting LDAP for that matter is a common requirement of almost all portal solutions. That’s the exact reason Liferay has addressed this requirement out of the box (OOB). But in a several cases, business specific rules are involved in user import activity. Which makes it appropriate to go for custom User Import module. 

Liferay exposes a set of API, which is as rich as you’ll need to import users from external directory server. This article is outcome of a successfully implemented User Import module for a client. And contains suggestions which can keep one from falling in to same pitfalls. On the other hand, it is as “high level” as possible so implementers can design as they choose.

Divide and Conquer

Considering Active Directory server as your LDAP source lets break the problem of User Import into parts. 

Reading users from LDAP

Searching directory Server using LDAP

LDAP stands for Light weight Directory Access Protocol. It defines an inter-operable standard API for applications to communicate with Directory Servers. Java’s support and API for LDAP is commonly referred to as Java Naming and Directory Interface (JNDI). See http://java.sun.com/products/jndi/ for more info. 

Consider these points when searching a Directory using JNDI:

  • Consider using connection pool when creating Context
  • Utilize JNDI’s search features. Provide filters and controls to narrow the search result and page the search results. You can learn about Search filters at http://java.sun.com/products/jndi/tutorial/basics/directory/filter.html. Active Directory has support for Paged result set. You can learn about Paged Results at http://java.sun.com/docs/books/tutorial/jndi/newstuff/paged-results.html.
  • Trade-off between page-size of search results. The lesser the page-size the more number of pages and hence more requests to server, but faster response from server. The more the page-size less number of pages and hence less requests to server, but slower response from server. Typically, page size of 100 is used.
  • Keep pool-size and page-size configurable, and same for all other connection parameters like, credentials, Server address etc.

Creating User objects 

Part of the challenge is to create a User object, which is akin to users in Liferay, i.e., users having identical attributes to Liferay’s users. This will take away many complexities. Consider creating an attribute mapper utility for this. And input to this utility should be configurable. At the simplest maintain a comma-separated list somewhere,

 ldapattrib1=liferayattrib1,ldapattrib2=liferayattrib2,…..,ldapattribn=liferayattribn

 Got a new attribute? Add to the above list, mapper utility reloads the mapping & you are good to go!

Similarly, if you are planning to update/insert users with roles and organizations membership info, have a mapping for them as well.

Custom Attributes

Consider using Liferay’s Custom User Attributes when corresponding attribute of LDAP is not available in Liferay OOB. Not only they serve the purpose, more of them can be added without a single bit of coding!! Custom attribute is a must know for any Liferay project implementer. Explore Liferay’s “Control Panel > Users > Custom Attributes” section to learn more.

Importing Users to Liferay

Try to abstract away details of implementation that reads users from LDAP. Import user should ideally be only concerned about adding/updating users to Liferay. It is not in interest of import service to know where users are coming from. This way you can easily reuse the same code for some other source of users, e.g. a database.

Liferay exposes a set API for working with Users. The exposed API is mostly consistent between local version and remote version (which is exposed as Web Service). 

Important Liferay APIs

  • UserSerivceSoap: Allows you to perform operations such as add, update, activate, deactivate Users
  • GroupServiceSoap: Important service for getting organizational group for users
  • RoleSerivceSoap: Important for getting organizational or group roles for users
  • UserGroupRoleServiceSoap: If you want to assign a user an organization role, this is the service for you
  • ExpandoValueServiceSoap: Use this service to add value of a custom attribute

 

To learn more about Groups, Roles, Organization see Liferay Admin Guide at http://www.liferay.com/documentation/liferay-portal/5.2/getting-started

Retrieving SOAP service instances

Handle to Liferay exposed WebSservice is retrieved through Locators implemented by Liferay. An example to get GroupServiceSoap will be: 

new GroupServiceSoapServiceLocator().getPortal_GroupService;

Similarly you can user service specific locator and get server instances of all the services listed in above section. Also notice that, Liferay API works on user Id (10144, in above e.g.) rather than user name.

Consider Update implications

It is very likely that after User Import module is done importing users, it will be required to update user information of existing users if LDAP server has some updated information for that user. This can lead to unwanted surprises. Take an example of a User, which was imported by the custom import module. Now, administrator assigns some roles to this user manually through Liferay Control Panel. Next time the module runs it overwrites this information with information coming from LDAP!! To handle this, clearly specify and conclude which attributes are additive in nature and which are overwritten. Attributes such as Role membership, Organization membership, Organization Role membership can be additive. To implement additive updates, pre-read the user’s attribute values from Liferay and create a composite set of values that contain both LDAP and Liferay values for that attribute. Call the update service with this composite set of values for that attribute. 

Scheduling

Even though not a must, scheduling can take away pains of an administrator by automatically triggering import jobs at desired time. Open Source scheduling frameworks like Quartz are enterprise ready. Quartz also recognizes Unix cron job syntax.

Summary

User Import is one module that has high chances of getting reused in your organization. So it should be kept as configurable as possible and as modularized as possible. Also, consider issues like time required to complete a run of module, because this is the period when Directory Server and Liferay will be out of sync.

 

Advait Trivedi,
Prinicipal Consultant,
CIGNEX India Office