In this three-parts article series I'm illustrating the implementation of the LDAP integration using a sample scenario: integrate Payara Server with a LDAP user directory and manage the authentication and authorization of a sample web application.
In Part 1, I showed you how to start the LDAP Server, while in Part 2 we configured the LDAP realm. Now you are probably wondering how to get the user’s information (first and last name, email address, etc.) that resides in the LDAP server. Unfortunately, the JAAS API doesn’t offer any standard mechanisms to access this user attributes in the directory tree. But there are other options available:
- Write your own custom LDAP realm that extends the
com.sun.enterprise.security.auth.realm.ldap.LDAPRealmclass and extract the user’s information into the current HTTP request. This can be difficult to code and you need the knowledge on how to configure Payara Server /GlassFish login modules as well.
- Use a third-party library to access the LDAP server and get the user’s information depending on the LDAP’s object tree. Personally, I favor this option since it’s easier to implement and offers more flexibility.
For our scenario, we are going to implement a CDI bean service that will use the OpenDJ’s Java SDK to connect to the LDAP server and retrieve the user information. Considering that any other SDK can be also used to complete this task I have chosen the OpenDJ SDK for the sake of consistency. We will add its Maven dependency into our POM file:
We also need to add the ForgeRock releases repository so Maven can download this dependency correctly:
Now, we will implement a service that will retrieve a User object base on the username/principal that is currently authenticated:
First, notice that our service initializes an instance of a
LDAPConnectionFactory. This object will create connections that will execute queries for objects to our LDAP server. These queries are executed in the
getUser method, by opening a new connection to the server, creating a new search request using the
Requests object and finally passing this request to the
searchSingleEntry method of the connection object. The filter query in question is (uid=%s) , which will look for all users that match the supplied UID (username) under the supplied base directory name (
If the search cannot find the user in the LDAP server, an
ErrorResultException will be thrown by the API to signal this result. Otherwise, if the search is successful, a SearchResultEntry object will be created so we can extract the user’s attributes (CN, SN, GivenName and Mail). This is the code for our
Now, we will proceed to update the landing page to show this information appropriately. First, we need to update the
WelcomeBean component so it can reference this newly coded service:
Then, we update the
index.html file and add the corresponding bean properties in the markup:
And finally, we run our application again to observe the outcome:
I’d recommend configuring the
UserService component in a production environment so that it retrieves the server’s location (hostname and port) and the base directory name (Base DN) using the custom JNDI resources feature offered by Payara Server /GlassFish. This way the information is decoupled from the code and it also helps in the implementation of separate environments for testing and production scenarios.
Integrating Payara Server with a LDAP directory is quite easy. You must be acquainted with the manner your organization’s user directory is structured but otherwise the task is simple enough and can be done in almost all environments. Using the JAAS API shipped with Java EE, it’s possible to have the server handle authentication and authorization seamlessly and with little changes.
If, for example, your organization uses Microsoft’s Active Directory, it’s also easy to change the properties of the security realm to integrate with it, since AD mimics the standard LDAP implementation with little differences. Coupled with the use of a third-party API to access the information stored in the directory, any Java EE application can retrieve additional information and use it to complement its functionality for the better.