Skip to main content

Glassfish Security Realm - LDAP Realm

Posted by tchangu on January 21, 2007 at 10:35 AM PST

Set up

For this experimentation, I used OpenLDAP that was bundled along with Redhat Fedora Core 5. Here is an overview of the steps required to configure an LDAP Realm. In FC5, the directory server can be started by executing the LDAP Server deamon - slapd, which can be found in /usr/sbin directory. The server deamon uses the configuration file slapd.conf which can be found in /etc/openldap directory.



Out of the box, the configuration file has defaults and so if someone is starting with defaults then this file needs to be edited to enable aspects like security, acl, directory database definitions etc. First the suffix and rootdn entries need to be edited. The rootdn defines the Distinguished Name (DN) of the root, which has no applicable access control limits i.e. the rules defined for normal access directives does not apply for rootdn. Technically this entry could be used initially to build the directory and once that task is done the rootdn entry could be removed from the configuration file for added security. The rootpw defines the password for the rootdn. The password can be in clear text or can use the password-hash (or {crypt}) format. The password hash can be created using the slappasswd utility found in /usr/sbin/ directory. The suffix directive defines the Distinguished Name (DN) of the top most node in the Directory Information Tree (DIT).




Note: Often the terms suffix, root and base are used interchangeably to denote the same concept. The following entry from slapd.conf file with suffix, rootdn, and rootpw modified.


##################################################
# ldbm and/or bdb database definitions
##################################################
database      bdb
suffix        "dc=namchi,dc=com"
rootdn        "cn=Manager,dc=namchi,dc=com"
rootpw        {CRYPT}-hRH2Qd3I15SE



Before the data can be loaded, the LDAP server needs to be up and running. The server could be started by running the slapd deamon (/usr/sbin/slapd) from the terminal (typically requires root access). To check if the server is up and running one could query the running process by - ps -ef | grep slapd. The deamon process also writes the process id in the file /var/run/openldap/slapd.pid. Once the server is up and running we can populate user data in the directory server. This is accomplished by - ldapadd command with a LDAP Data Interchange Format (LDIF) file as one of the argument. The LDIF is a standard data interchange format for representing (LDAP) directory content as well as directory update (Add, Modify, Delete, Rename) requests.




Before we can add user data we need to add base information to the directory. This is specified in the following ldif file.
# comment
dn: dc=namchi,dc=com
dc: namchi
description: Namchi is in Sikkim
objectClass: dcObject
objectClass: organization
o: namchi.com

dn: ou=Users,dc=namchi,dc=com
ou: Users
objectClass: organizationalUnit

dn: ou=Groups,dc=namchi,dc=com
ou: Groups
description: Group List
objectClass: top
objectClass: organizationalUnit



The entries defined in this base ldif file is added to the directory by executing - ldapadd -x -D "cn=Manager,dc=namchi,dc=com" -W -f base.ldif. Here in addition to the ldif file we pass additional parameters as well. We used -x to specify that we want to use simple authentication instead of SASL. We used -D to tell what the Distinguished Name (DN) is. We used -W to prompt for password for use in simple authentication. We used -f to specify the file that contains the ldap entries. Of course the ldapadd command line interface has a wide array of options, which can be found here.


Once the base is defined we are now ready to create users and groups. The following entries defines the user and group information.



Users
dn: uid=testusr01,ou=Users,dc=namchi,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: testusr01
cn: Joe User
sn: User
givenName: Joe
title: Analyst
telephoneNumber: +0 000 000 0000
mobile: +0 000 000 0000
postalAddress: AddressLine1$AddressLine2$AddressLine3
userPassword: {CRYPT}frmw3hal/BVcU
labeledURI: http://test.namchi.com/
loginShell:
/bin/bash
uidNumber: 10000
gidNumber: 2000
homeDirectory: /users/testusr01/
description: A Test User for testing LDAP Authn



Now we add the user entries to the directory by executing the following command: ldapadd -x -D "cn=Manager,dc=namchi,dc=com" -W -f users.ldif




Groups
dn: cn=group01,ou=Groups,dc=namchi,dc=com
objectClass: top
objectClass: groupOfUniqueNames
uniqueMember: uid=testusr01,ou=Users,dc=namchi,dc=com
cn: group01



Now we add the group entries to the directory by executing the following command: ldapadd -x -D "cn=Manager,dc=namchi,dc=com" -W -f groups.ldif. To ensure that data got added correctly, we can list the entries by invoking the following command: ldapsearch -x -b 'dc=namchi,dc=com' '(objectclass=*)'. This will list all the entries.




Now that the data is loaded in ldap directory we are now ready to configure Glassfish LDAP realm. First we need to create a LDAP realm. Assuming the Glassfish Application server is up and running we could navigate to the following location in the admin console (http://domain:4848) -> Application Server: Configuration -> Security -> Realm -> New The following screen shot demonstrates how to do this

LdapRealm_FF.jpg


Figure 1.0 Admin Console - LDAP Realm




The LDAP Realms requires that following mandatory properties to be specified

  • directory - The URL of the directory server. For example ldap://192.168.0.119:389
  • base-dn - Base Distinguished Name (DN) for the location of user data. This 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. For example: dc=namchi,dc=com
  • jaas-context - Type of login module to use for this realm. This must be ldapRealm



The following table specifies optional properties

  • search-filter - Search filter to use to find the user. The default value is uid=%s (%s expands to the subject name). This in our case would expand to - uid=testusr01
  • 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. The default value is uniquemember=%d (%d expands to the user element DN). This in our case would expand to - uniquemember=uid=testusr01,ou=Users,dc=namchi,dc=com
  • group-target - LDAP attribute name that contains group name entries. The default value is 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.



This pretty much completes the configuration necessary to create the LDAP Realm.



Testing
First the security roles needs to be defined either using the @DeclareRoles annotation in the servlet or by using security-role-ref in web.xml. Of course the annotation is preferred method for specifying roles. Next the security-constraint needs to be specified and following xml snippet from web.xml demonstrates the idea

<security-constraint>
  <web-resource-collection> <web-resource-name>Testing</web-resource-name>
    <url-pattern>/protected/*</url-pattern>
    <http-method>GET</http-method>
    <http-method>POST</http-method>
  </web-resource-collection>
  <auth-constraint>
    <role-name>Protected</role-name>
  </auth-constraint>
</security-constraint>



How the user is authenticated is taken care by the login-config element The following xml snippet demonstrates this.


<login-config>
   <auth-method>FORM</auth-method>
   <realm-name>LDAPRealm</realm-name>
   <form-login-config>
      <form-login-page>/pages/logon.jsp</form-login-page>
       <form-error-page>/pages/logonError.jsp</form-error-page>
   </form-login-config>
</login-config>

Next map the roles defined in web.xml to groups defined in the LDAP server. The security-role-mapping element of - sun-web.xml takes care of this.
</sun-web-app>
...
  <security-role-mapping>
    <role-name>Protected</role-name>
    <group-name>group01</group-name>
  </security-role-mapping>
</sun-web-app>

Thats it & Enjoy

Related Topics >>