You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Peter Meigs <pm...@javaxpresso.com> on 2006/01/08 18:24:48 UTC

Using JNDIRealm to authenticate against MS ActiveDirectory

In my company, our users mostly use Windows 2000/XP as their desktop.  Our application serves are normally run on some flavor of Unix and could be Solaris, Linux, or AIX.  To make our corporate security folks happy, I'd like to authenticate our Tomcat users against the MS Active Directory that supports the desktop logins and have been able to accomplish this.

The idea is to create Windows global groups in a Domain and then make users members of these groups.  This is a normal thing to do in Windows and there is Windows Software to support this.  These group names would become the role names that could be used in the web.xml or as an argument to the isUserInRole() method.

The server.xml definition that worked for me is (company name changed to a generic company.com)

<Realm alternateURL="ldap://DOMAINCONTROLLER2.company.com:389" 
className="org.apache.catalina.realm.JNDIRealm" 
connectionName="jndiauthenticate@company.com" connectionPassword="authenticationPassword" connectionURL="ldap://DOMAINCONTROLLER1.company.com:389" 
contextFactory="com.sun.jndi.ldap.LdapCtxFactory" debug="99" 
roleBase="OU=ApplicationRoles,OU=Groups,OU=USA,DC=company,DC=com" 
roleName="cn" 
roleSearch="member={0}" 
roleSubtree="true" 
userBase="OU=Users,OU=USA,DC=company,DC=com" 
userSearch="(mail={0}@company.com)" 
userSubtree="false">
</Realm>

It was interesting to me that in ActiveDirectory, the email address seemed to work for finding the users.

This works fine except the roles are two closely tied to the users.  I'd like to see a three tier structure where we have users, roles, and capabilities.  I'm redefining the word "role" here now a little from what Tomcat used before but I think what I am proposing will work out.  

I'd like to assign capabilites to roles and then assign roles to users.  In the Windows Active Directory, this works out because users have a memberOf attribute that say what Groups they are members of, but it turns out that Groups can be memberOf other Groups.  My convention for this is to make capabilities start with the word "Can" and roles start with the word "Role".  So we could have capabilites CanLogin, CanUpdateDataBase, CanRunSpecialApp and roles RoleBasicUser, RoleAdvancedUser, RolePrivilegedUser.  A user would be a memberOf RoleAdvancedUser for example.  All roles imply the ability to log in, so all Roles would be memberOf CanLogin.  RoleAdvancedUser would also me a memberOf CanRunSpecialApp.

I've looked at the code in JNDIRealm and it only supports Users as memberOf a (in my terminology) a capability.  I created a new module I call ActiveDirRealm that accomplishes this.  The module is a few changes to JNDIRealm.  It also adds a parameter roleLink to specify the memberOf attribute.  I have tested it in my environment and it seems to work.  The server,xml then becomes:

<Realm alternateURL="ldap://DOMAINCONTROLLER2.company.com:389" 
className="org.apache.catalina.realm.JNDIRealm" 
connectionName="jndiauthenticate@company.com" connectionPassword="authenticationPassword" connectionURL="ldap://DOMAINCONTROLLER1.company.com:389" 
contextFactory="com.sun.jndi.ldap.LdapCtxFactory" debug="99" 
roleBase="OU=ApplicationRoles,OU=Groups,OU=USA,DC=company,DC=com" 
roleName="cn" 
                  roleLink="memberOf"
roleSearch="member={0}" 
roleSubtree="true" 
userBase="OU=Users,OU=USA,DC=company,DC=com" 
userSearch="(mail={0}@company.com)" 
userSubtree="false">
</Realm>

I think this would be a nice addition to JNDIRealm but I'm not sure how to propose this for a future Tomcat.  I'm happy to share my implementation of ActiveDirRealm but it is too large to include here (about 1800 lines, similar to JNDI Realm)

Another question I have is whether this should be an extension to JNDIRealm or a separate module.

Peter Meigs
pmeigs@javaxpresso.com