You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Philippe Maseres <p....@citb.bull.net> on 2003/03/13 15:59:24 UTC

JNDI realm - recursive group/role matching (Tomcat 4.1.18)

Hello all.

I need to set up Tomcat to use a LDAP directory for authentication and
authorization. I successfully configured my iPlanet directory and a JNDI
realm in Tomcat, and users and roles checkings work well, but with a
restriction. My directory schema, which is quite classical, provides a
dedicated tree with two sub-trees : one for users and another for groups.
Users assignment in groups is made through the common multivalued attribute
'uniqueMember'. According to my JNDI realm setup, Tomcat matches users from
groups using their DN and deduces the right roles. However, i need to
organize users in the directory in a hierarchic classification where persons
don't belong directly to groups that represent applications roles. At the
opposite, users are assigned to profiles themselves forming a compound tree
which terminal leaves are the actual roles mapped to the applications
constraints. Unfortunately, Tomcat seems not to process the role matching
recursively, ie. retrieving first groups from the user's DN, and then groups
from each found group. In a past project, the BEA Weblogic LDAP realm was
used to perform such a recursive matching with no particular setting. Is
there any way to use Tomcat the same way, with its JNDI realm implementation
? Is there any alternative JNDI realm that could be used, or should i
implement it myself ?
I tried to create a new class extending the Catalina's JNDIRealm, and
override the getRoles() method to add the desired behaviour. See the code
bellow. But i add two problems to achieve this work :
a) the method take a parameter of type 'User' which is a 'package' scope
class. So i tried again putting my class in the org.apache.catalina.realm
package... Uggly !!!
b) the MBean which is associated to the JNDIRealm is set up instantiating
the clas with a 'new JNDIRealm()' statement, which seems to lead to an
exception at startup. Nevertheless, my class seems to work well... I bet
it's not the preferred way to subclass the catalina's component !
For all that, i suppose this functionality should be taken into account
another way...

Thanks for answers and help...

Philippe Maseres

<<< NEW getRoles() CODE >>>

package org.apache.catalina.realm;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

public class SmartJNDIRealm extends JNDIRealm {

	protected List getRoles(final DirContext dirContext, final User user)
throws NamingException {

		List plainList = super.getRoles(dirContext, user);
		if (plainList == null)
			return plainList;

		HashSet recursiveSet = new HashSet();

		for (Iterator i = plainList.iterator(); i.hasNext();) {
			String groupName = (String) i.next();
			recursiveGroupSearch(dirContext, recursiveSet, groupName);
		}

		if (debug >= 2) {
			log("  * Returning set with " + recursiveSet.size() + " roles");
			for (Iterator i = recursiveSet.iterator(); i.hasNext();)
				log("  * - Recursively found role " + i.next());
		}

		return new ArrayList(recursiveSet);

	}

	protected void recursiveGroupSearch(final DirContext dirContext, Set
recursiveSet, String groupname) throws NamingException {
		if (debug >= 3)
			log("  *** Recursive search for group '" + groupname + "'");
		//	Adding the given group to the result set if not already found
		if (!recursiveSet.contains(groupname)) {
			recursiveSet.add(groupname);
			//	Prepare the parameters for searching groups
			String filter = roleFormat.format(new String[] { roleName + "=" +
groupname + "," + roleBase });
			SearchControls controls = new SearchControls();
			controls.setSearchScope(roleSubtree ? SearchControls.SUBTREE_SCOPE :
SearchControls.ONELEVEL_SCOPE);
			controls.setReturningAttributes(new String[] { roleName });
			if (debug >= 3) {
				log("  * Searching recursively role base '" + roleBase + "' for
attribute '" + roleName + "'");
				log("  * With filter expression '" + filter + "'");
			}
			//	Searching groups that assign the given group
			NamingEnumeration gne = context.search(roleBase, filter, controls);
			if (gne != null) {
				//	Iterate over the resulting groups
				while (gne.hasMore()) {
					SearchResult sr = (SearchResult) gne.next();
					Attributes attributes = sr.getAttributes();
					if (attributes != null) {
						Attribute attribute = attributes.get(roleName);
						if (attribute != null)
							recursiveGroupSearch(dirContext, recursiveSet, (String)
attribute.get());
					}
				}
			}
		}
	}

	public String getInfo() {
		return "org.apache.catalina.realm.SmartJNDIRealm/1.0";
	}

	protected String getName() {
		return "SmartJNDIRealm";
	}

}


---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org