Hello.

I know it's not trivial, but it could be done. Below, a quicly done test
class that overrides the JNDIRealm to retrieve groups from groups. As i
explained in another mail i posted in the developer mailing list, the main
problem is not the code to do it, but how integrate it within Tomcat : the
JNDIRealm uses 'package scoped' classes, and if you want to change it you
must either create your new class with few overriden methods in the same
package, and it's not very "elegant", or rewrite a full implementation. For
that, as this new feature is probably as common as to be integrated in the
Tomcat delivery, i hope one of the apache's members takes it into account in
a future version of the JNDIRealm.

Regards.

<<< 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";
        }

}

Philippe Maseres

<<<Philippe>>> -----Message d'origine-----
<<<Philippe>>> De : Jon Roberts [mailto:[EMAIL PROTECTED]
<<<Philippe>>> Envoye : jeudi 13 mars 2003 20:21
<<<Philippe>>> A : Tomcat Users List
<<<Philippe>>> Objet : Re: JNDI realm - recursive group/role
<<<Philippe>>> matching (Tomcat 4.1.18)
<<<Philippe>>>
<<<Philippe>>>
<<<Philippe>>> I can't speak for tomcat, but I can say that what
<<<Philippe>>> you are asking is not
<<<Philippe>>> trivial. LDAP was not designed to support multi-join
<<<Philippe>>> queries. However,
<<<Philippe>>> as I recall the iPlanet/Sun ONE directory server has
<<<Philippe>>> a feature called
<<<Philippe>>> "dynamic groups" that may help you solve this
<<<Philippe>>> problem on the directory side.
<<<Philippe>>>
<<<Philippe>>> Jon Roberts
<<<Philippe>>> www.mentata.com
<<<Philippe>>>
<<<Philippe>>> Philippe Maseres wrote:
<<<Philippe>>> > Hello all.
<<<Philippe>>> > I need to set up Tomcat to use a LDAP directory
<<<Philippe>>> for authentication and
<<<Philippe>>> > authorization. I successfully configured my
<<<Philippe>>> iPlanet directory and a JNDI
<<<Philippe>>> > realm in Tomcat, and users and roles checkings
<<<Philippe>>> work well, but with a
<<<Philippe>>> > restriction. My directory schema, which is quite
<<<Philippe>>> classical, provides a
<<<Philippe>>> > dedicated tree with two sub-trees : one for users
<<<Philippe>>> and another for groups.
<<<Philippe>>> > Users assignment in groups is made through the
<<<Philippe>>> common multivalued attribute
<<<Philippe>>> > 'uniqueMember'. According to my JNDI realm setup,
<<<Philippe>>> Tomcat matches users from
<<<Philippe>>> > groups using their DN and deduces the right roles.
<<<Philippe>>> However, i need to
<<<Philippe>>> > organize users in the directory in a hierarchic
<<<Philippe>>> classification where persons
<<<Philippe>>> > don't belong directly to groups that represent
<<<Philippe>>> applications roles. At the
<<<Philippe>>> > opposite, users are assigned to profiles
<<<Philippe>>> themselves forming a compound tree
<<<Philippe>>> > which terminal leaves are the actual roles mapped
<<<Philippe>>> to the applications
<<<Philippe>>> > constraints. Unfortunately, Tomcat seems not to
<<<Philippe>>> process the role matching
<<<Philippe>>> > recursively, ie. retrieving first groups from the
<<<Philippe>>> user's DN, and then groups
<<<Philippe>>> > from each found group. In a past project, the BEA
<<<Philippe>>> Weblogic LDAP realm was
<<<Philippe>>> > used to perform such a recursive matching with no
<<<Philippe>>> particular setting. Is
<<<Philippe>>> > there any way to use Tomcat the same way, with its
<<<Philippe>>> JNDI realm implementation
<<<Philippe>>> > ? Is there any alternative JNDI realm that could
<<<Philippe>>> be used, or should i
<<<Philippe>>> > implement it myself ?
<<<Philippe>>> > Thanks for answers...
<<<Philippe>>>
<<<Philippe>>>
<<<Philippe>>> -----------------------------------------------------
<<<Philippe>>> ----------------
<<<Philippe>>> To unsubscribe, e-mail:
<<<Philippe>>> [EMAIL PROTECTED]
<<<Philippe>>> For additional commands, e-mail:
<<<Philippe>>> [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to