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="[EMAIL PROTECTED]" 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="([EMAIL PROTECTED])" 
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="[EMAIL PROTECTED]" 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="([EMAIL PROTECTED])" 
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
[EMAIL PROTECTED]









Reply via email to