Tomcat And LDAP

Overview#

Using the JNDI Directory Realm with Tomcat can save application developers a lot of time and frustration.

Be sure to check the current Tomcat documentation for the version you are using. This was initially performed on Tomcat version 6

Form Apache's Site The Realm Component

The JNDI Directory Realm connects Catalina (Tomcat) to an LDAP Directory, accessed through an appropriate JNDI driver, that stores usernames, passwords, and their associated roles. Changes to the directory are immediately reflected in the information used to authenticate new logins.

The directory realm supports a variety of approaches to using LDAP for authentication:

A rich set of additional attributes lets you configure the required behavior as well as the connection to the underlying directory and the element and attribute names used to retrieve information from the directory:


Real Life Implementations.#

Disclaimers#

This is a very simple Example and does not address many items of the implementation. Contact Us for more details.

Now adding some practicalities to this discussion for "real life" implementations.

First let us look at the variety of approaches to using LDAP for authentication.

Pattern Distinguished Name (DN)#

"The realm can either use a pattern to determine the distinguished name (DN) of the user's directory entry, or search the directory to locate that entry."

Authenticate or Performing a Comparison#

"The realm can authenticate the user either by binding to the directory with the DN of the user's entry and the password presented by the user, or by retrieving the password from the user's entry and performing a comparison locally. "

Never perform a Password Comparison. Comparing the LDAP entries password typically bypasses the LDAP server's built-in controls for such items as:

Group Entries or Values of an Attribute#

Groups are Bad and it is a Best practice to avoid groups in all but the smallest LDAP directories. It is recommended to use Container Authentication and Authorization Using User Attribute Values for Tomcat Role

The Bottom Line(s)#

How To Use JNDI#

You will typically need to modify two files to setup Tomcat to use JNDI with LDAP. The server.xml file will define the Security Realms and the application's web.xml file will define the "Security Constraints".

Security Realms#

A security realm is a mechanism used for protecting Web application resources. It gives you the ability to protect a resource with a defined security constraint and then define the user roles that can access the protected resource. Tomcat has this type of realm functionality built in.

Modify the $CATALINA_HOME/conf/server.xml file and configure the Realm. The modification need to be something like shown below.

      <Realm className="org.apache.catalina.realm.JNDIRealm" debug="10"
                                connectionURL="ldaps://192.168.0.8:636"
                                alternateURL="ldap://192.168.0.7:636"
                                userBase="ou=people,dc=willeke,dc=com"
                                userSearch="(cn={0})"
                                userSubtree="true"
                                userRoleName="dictcrole"
                                connectionName="cn=admin,ou=...,dc=willeke,dc=com"
                                connectionPassword="removed"
                /> 
The realm configuration is using LDAPS to contact the LDAP server and requires that the certificate be imported to the JVM Keystore that tomcat is using.

To use a different Truststore than the cacerts Truststore of the JVM you need to set the javax.net.ssl.trustStore path or on current Tomcat versions use:

Another example and some more detailed LDAP information is provided here: Using User Attribute Values for Tomcat Roles

The Directory Engineering Group can not recommend the use of non-LDAPS when performing a bind as the password is not protected on the wire.

Please do not try to use the items exactly as shown as this is only an example and as this deals with the security of an application you must be careful.

Attribute Definitions#

These are the XML Attributes of the XML Element Realm and what the values represent: To "protect" an Tomcat Application, then you will need to modify the web.xml file for the application. Typically, it is found $CATALINA_HOME/webapps/DirectoryWiki/WEB-INF
<web-app>
...
   <!--  START OF ACCESS RESTRICTION -->
   <security-constraint>
       <web-resource-collection>
           <web-resource-name>Administrative Area</web-resource-name>
           <url-pattern>/Delete.jsp</url-pattern>
       </web-resource-collection>
       <auth-constraint>
           <role-name>Admin</role-name>
       </auth-constraint>
       <user-data-constraint>
           <transport-guarantee>CONFIDENTIAL</transport-guarantee>
       </user-data-constraint>
   </security-constraint>
      
   <security-constraint>
       <web-resource-collection>
           <web-resource-name>Authenticated area</web-resource-name>
           <url-pattern>/Edit.jsp</url-pattern>
           <url-pattern>/Comment.jsp</url-pattern>
           <url-pattern>/Login.jsp</url-pattern>
           <url-pattern>/NewGroup.jsp</url-pattern>
           <url-pattern>/Rename.jsp</url-pattern>
           <url-pattern>/Upload.jsp</url-pattern>
           <http-method>DELETE</http-method>
           <http-method>GET</http-method>
           <http-method>HEAD</http-method>
           <http-method>POST</http-method>
           <http-method>PUT</http-method>
       </web-resource-collection>

       <web-resource-collection>
           <web-resource-name>Read-only Area</web-resource-name>
           <url-pattern>/attach</url-pattern>
           <http-method>DELETE</http-method>
           <http-method>POST</http-method>
           <http-method>PUT</http-method>
       </web-resource-collection>

       <auth-constraint>
           <role-name>Admin</role-name>
           <role-name>Authenticated</role-name>
       </auth-constraint>

       <user-data-constraint>
           <transport-guarantee>CONFIDENTIAL</transport-guarantee>
       </user-data-constraint>
   </security-constraint>

   <login-config>
       <auth-method>FORM</auth-method>
       <form-login-config>
           <form-login-page>/LoginForm.jsp</form-login-page>
           <form-error-page>/LoginForm.jsp</form-error-page>
       </form-login-config>
   </login-config>

   <security-role>
       <description>
           This logical role includes all authenticated users
       </description>
       <role-name>Authenticated</role-name>
   </security-role>

   <security-role>
       <description>
           This logical role includes all administrative users
       </description>
       <role-name>Admin</role-name>
   </security-role>
   ...
</web-app>

What This Means#

Typically, the user will provide their "uid" and password on a form provided by the developer. The Realm will search for the User Entry and return the Fully Distinguished Name (FDN).

The Realm will then try to authenticate the user with the FDN, from above and compare the values of the LDAP Attribute "tomcatRole" to the Realm Constraint provided in the WEB.XML file. In the example above, the <role-name>*</role-name> implies anyone that can authenticate will be allowed regardless of the value defined in the userRoleName="roomNumber".

If the user can Authenticate and the value(s) of the tomcatRole match the Realm Constraint provided, the user is allowed access.

If the <auth-constraint> was defined as:

       <auth-constraint>
           <role-name>jim</role-name>
           <role-name>molly</role-name>
           <role-name>scott</role-name>
       </auth-constraint>
Then only users with the persons who could authenticate who have the uid values of B003281, E178093 or U657045 would pass the auth-constraint and be allowed to access the application.

Things To Watch#

Make It Secure#

First, all LDAP and HTTP authentication should be done via Secure connections. As values passed (Like passwords) over "simple" LDAP Bind Requests or HTTP are in clear text and therefore could expose password values. Refer to Tomcat And SSL for information on http for Tomcat.

LDAP Trace#

When we look at the setup from a trace, we see the searchRequest by the tomcatadmin account from tomcat Server (192.168.0.15) and then a bind of the user (jim): (We did this over cleartext)
18:10:18 7E50AB90 LDAP: (192.168.1.15:39539)(0x0009:0x60) DoBind on connection 0x15446a00
18:10:18 7E50AB90 LDAP: (192.168.1.15:39539)(0x0009:0x60) Bind name:cn=tomcatadmin,dc=willeke,dc=com, version:3, authentication:simple
18:10:18 7E50AB90 LDAP: (192.168.1.15:39539)(0x0009:0x60) Sending operation result 0:"":"" to connection 0x15446a00
18:10:18 7EEBDB90 LDAP: (192.168.1.15:39539)(0x000a:0x63) DoSearch on connection 0x15446a00
18:10:18 7EEBDB90 LDAP: (192.168.0.15:39539)(0x000a:0x63) Search request:
   base: "ou=people,dc=willeke,dc=com"
   scope:2 dereference:3 sizelimit:0 timelimit:0 attrsonly:0
   filter: "(cn=jim)"
   attribute: "dictcrole"
18:10:18 7EEBDB90 LDAP: (192.168.0.15:39539)(0x000a:0x63) nds_back_search: Search Control OID 2.16.840.1.113730.3.4.2
18:10:18 7EEBDB90 LDAP: (192.168.0.15:39539)(0x000a:0x63) Sending search result entry "cn=jim,ou=people,dc=willeke,dc=com" to connection 0x15446a00
18:10:18 7EEBDB90 LDAP: (192.168.0.15:39539)(0x000a:0x63) Sending operation result 0:"":"" to connection 0x15446a00
18:10:18 AB3F0B90 LDAP: (192.168.0.15:39539)(0x000b:0x60) DoBind on connection 0x15446a00
18:10:18 AB3F0B90 LDAP: (192.168.0.15:39539)(0x000b:0x60) Bind name:cn=jim,ou=people,dc=willeke,dc=com, version:3, authentication:simple
18:10:18 AB3F0B90 LDAP: (192.168.0.15:39539)(0x000b:0x60) Sending operation result 0:"":"" to connection 0x15446a00

More Information#

There might be more information for this subject on one of the following: