Friday Jan 26, 2007

Glassfish OpenDS integration

There's little need to explain why one would want to integrate application authentication with a centralized LDAP server so I'll get right to business. For test purposes I'm using the OpenDS directory and the Glassfish application server. In case you haven't heard, OpenDS is a 100% pure Java, open source, directory server specifically designed for large deployments where high performance is critical and ease of management is required. And, of course, Glassfish is a JEE 5 compliant application server.

To get started, you'll first need to install an OpenDS instance. Installation is made quick and easy via the "Quick Setup" Web Start installer and step-by-step instructions. During the installation process note the installation path, LDAP listener port, administrative User DN/password and the Directory Base DN as you'll need these properties to configure the Glassfish realm.

Next, load sample users and groups into OpenDS. The sample data is provided in LDIF format as it is the quickest and easiest method to import data into OpenDS. For test purposes I defined a single group, "webappgroup", with 1 member "treydrake". An additional user "noaccess" is defined to verify the solution works. Note that the web.xml, defined at the bottom of the page, grants access only to members of the group "webappgroup".

# add group
dn: ou=Groups,dc=example,dc=com
changetype: add
ou: Groups
description: Group ou
objectClass: top
objectClass: organizationalUnit

# add people ou
dn: ou=People,dc=example,dc=com
changetype: add
ou: People
description: People
objectClass: top
objectClass: organizationalUnit

# add an authorized user (belongs to the group webappgroup)
dn: uid=treydrake,ou=People,dc=example,dc=com
changetype: add
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: treydrake
cn: Trey Drake
sn: Drake
givenName: Trey
userPassword: password

# unauthorized user
dn: uid=noaccess,ou=People,dc=example,dc=com
changetype: add
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: noaccess
cn: No Access
sn: access
givenName: no
userPassword: noaccess

# add user to the webapp group
dn: cn=webappgroup,ou=Groups,dc=example,dc=com
changetype: add
objectClass: top
objectClass: groupOfUniqueNames
uniqueMember: uid=treydrake,ou=People,dc=example,dc=com
cn: webappgroup

Use the ldapmodify tool included in the OpenDS install to import the LDIF file as shown below. In the following examples I assume OpenDS is installed locally, the port is 1389, and the administrative user/password is the default "Directory Manager"/"password". If you customized the install and/or need to use more advanced options type "ldapmodify -H" to get complete usage info. For example:

~/OpenDS/bin treydrake$ ~/OpenDS/bin/ldapmodify -p 1389 -a -D "cn=Directory Manager" -w password -f ~/dev/opendsglassfishrealm-wksp/opendsauthtest/ldifs/data.ldif

Use ldapsearch to verify that the new user 'treydrake' can successfully authenticate to OpenDS and that the user is a member of the webappgroup. For example:

~/OpenDS/bin treydrake$ ~/OpenDS/bin/ldapsearch -p 1389 -D "uid=treydrake,ou=People,dc=example,dc=com" -w password -b ou=Groups,dc=example,dc=com objectclass=groupofuniquenames

Next, add an OpenDS realm to the Glassfish application server via the Glassfish console. Login to the console; e.g., http://localhost:4848 and navigate to Configuration -> Security -> Realms and click the "New" button. See the screen shot below for property settings:

The Glassfish LDAP realm requires the following properties:
  • directory - LDAP URL to the OpenDS instance; e.g., ldap://localhost:1389
  • base-dn - Base Distinguished Name (DN) for the location of user data, which can be at any level above the user data, since a tree scope search is performed. The smaller the search tree, the better the performance.
  • jaas-context - Must be "ldapRealm".
The following properties are optional:
  • search-filter - Search filter to use to find the user. The default value is uid=%s (%s expands to the subject name).
  • group-base-dn - Base DN for the location of group data. Same as the base-dn but it can be tuned if necessary.
  • group-search-filter - Search filter to find group memberships for the user. Defaults to uniquemember=%d (%d expands to the user element DN).
  • group-target - LDAP attribute name that contains group name entries. Defaults to CN.
  • search-bind-dn - Optional DN used to authenticate to the directory for performing the search-filter lookup. Only required for directories that do not allow anonymous search.
  • search-bind-password - LDAP password for the DN given in search-bind-dn.

Next, configure the web.xml and sun-web.xml descriptors to authenticate using the OpenDS realm by adding the security-constraint and login-config elements to your application's web.xml file and the role <-> group mapping in sun-web.xml. See samples below: web.xml

<web-app version="2.4"


<!-- grant access to all users that possess the role
'secure' and deny all others -->


<!-- declare the app uses FORM based authentication
using your newly created OpenDS realm -->


The Glassfish specific descriptor (sun-web.xml) maps the web application role defined in the web.xml descriptor to a LDAP group. sun-web.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sun-web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Application Server 8.1 Servlet 2.4//EN"

Finally, deploy your application and attempt to login using the username "treydrake" and password "password". Authenticating as "noaccess", or any other user for that matter, should fail. For convenience sake, I've uploaded a web application that's configured using the above instructions. Good luck.




« February 2016