Author: fhanik Date: Sat Jun 30 01:08:37 2012 New Revision: 1355617 URL: http://svn.apache.org/viewvc?rev=1355617&view=rev Log:
With more and more use of RFC 2307 http://tools.ietf.org/html/rfc2307 There is a new way to search for roles using the memberUid that can contain the value of another attribute within the users directory entry. This may not be very specific to 2307, but that is where I see this combination of role searches occur the most. Example: http://www.openldap.org/lists/openldap-technical/200904/msg00024.html Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/realm/JNDIRealm.java tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml tomcat/tc7.0.x/trunk/webapps/docs/config/realm.xml Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/realm/JNDIRealm.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/realm/JNDIRealm.java?rev=1355617&r1=1355616&r2=1355617&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/realm/JNDIRealm.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/realm/JNDIRealm.java Sat Jun 30 01:08:37 2012 @@ -126,8 +126,9 @@ import org.ietf.jgss.GSSCredential; * property.</li> * <li>The <code>roleSearch</code> pattern optionally includes pattern * replacements "{0}" for the distinguished name, and/or "{1}" for - * the username, of the authenticated user for which roles will be - * retrieved.</li> + * the username, and/or "{2}" the value of the userRoleAttribute + * attribute from the users entry, of the authenticated user + * for which roles will be retrieved.</li> * <li>The <code>roleBase</code> property can be set to the element that * is the base of the search for matching roles. If not specified, * the entire context will be searched.</li> @@ -298,6 +299,14 @@ public class JNDIRealm extends RealmBase */ protected String userPassword = null; + /** + * The name of the attribute inside the users + * directory entry where the value will be + * taken to search for roles + * This attribute is not used during a nested search + */ + protected String userRoleAttribute = null; + /** * A string of LDAP user patterns or paths, ":"-separated @@ -835,6 +844,14 @@ public class JNDIRealm extends RealmBase } + public String getUserRoleAttribute() { + return userRoleAttribute; + } + + public void setUserRoleAttribute(String userRoleAttribute) { + this.userRoleAttribute = userRoleAttribute; + } + /** * Return the message format pattern for selecting users in this Realm. */ @@ -845,6 +862,8 @@ public class JNDIRealm extends RealmBase } + + /** * Set the message format pattern for selecting users in this Realm. * This may be one simple pattern, or multiple patterns to be tried, @@ -1249,6 +1268,9 @@ public class JNDIRealm extends RealmBase list.add(userPassword); if (userRoleName != null) list.add(userRoleName); + if (userRoleAttribute != null) { + list.add(userRoleAttribute); + } String[] attrIds = new String[list.size()]; list.toArray(attrIds); @@ -1284,7 +1306,7 @@ public class JNDIRealm extends RealmBase // If no attributes are requested, no need to look for them if (attrIds == null || attrIds.length == 0) { - return new User(username, dn, null, null); + return new User(username, dn, null, null,null); } // Get required attributes from user entry @@ -1302,12 +1324,17 @@ public class JNDIRealm extends RealmBase if (userPassword != null) password = getAttributeValue(userPassword, attrs); + String userRoleAttrValue = null; + if (userRoleAttribute != null) { + userRoleAttrValue = getAttributeValue(userRoleAttribute, attrs); + } + // Retrieve values of userRoleName attribute ArrayList<String> roles = null; if (userRoleName != null) roles = addAttributeValues(userRoleName, attrs, roles); - return new User(username, dn, password, roles); + return new User(username, dn, password, roles, userRoleAttrValue); } @@ -1446,12 +1473,17 @@ public class JNDIRealm extends RealmBase if (userPassword != null) password = getAttributeValue(userPassword, attrs); + String userRoleAttrValue = null; + if (userRoleAttribute != null) { + userRoleAttrValue = getAttributeValue(userRoleAttribute, attrs); + } + // Retrieve values of userRoleName attribute ArrayList<String> roles = null; if (userRoleName != null) roles = addAttributeValues(userRoleName, attrs, roles); - return new User(username, dn, password, roles); + return new User(username, dn, password, roles, password); } @@ -1694,6 +1726,7 @@ public class JNDIRealm extends RealmBase String dn = user.getDN(); String username = user.getUserName(); + String userRoleId = user.getUserRoleId(); if (dn == null || username == null) return (null); @@ -1721,7 +1754,7 @@ public class JNDIRealm extends RealmBase return (list); // Set up parameters for an appropriate search - String filter = roleFormat.format(new String[] { doRFC2254Encoding(dn), username }); + String filter = roleFormat.format(new String[] { doRFC2254Encoding(dn), username, userRoleId }); SearchControls controls = new SearchControls(); if (roleSubtree) controls.setSearchScope(SearchControls.SUBTREE_SCOPE); @@ -1794,7 +1827,7 @@ public class JNDIRealm extends RealmBase Map<String, String> newThisRound = new HashMap<String, String>(); // Stores the groups we find in this iteration for (Entry<String, String> group : newGroups.entrySet()) { - filter = roleFormat.format(new String[] { group.getKey(), group.getValue() }); + filter = roleFormat.format(new String[] { group.getKey(), group.getValue(), group.getValue() }); if (containerLog.isTraceEnabled()) { containerLog.trace("Perform a nested group search with base "+ roleBase + " and filter " + filter); @@ -2378,9 +2411,11 @@ public class JNDIRealm extends RealmBase private final String dn; private final String password; private final List<String> roles; + private final String userRoleId; + public User(String username, String dn, String password, - List<String> roles) { + List<String> roles, String userRoleId) { this.username = username; this.dn = dn; this.password = password; @@ -2389,6 +2424,7 @@ public class JNDIRealm extends RealmBase } else { this.roles = Collections.unmodifiableList(roles); } + this.userRoleId = userRoleId; } public String getUserName() { @@ -2406,6 +2442,12 @@ public class JNDIRealm extends RealmBase public List<String> getRoles() { return roles; } + + public String getUserRoleId() { + return userRoleId; } + + +} } Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1355617&r1=1355616&r2=1355617&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Sat Jun 30 01:08:37 2012 @@ -56,6 +56,13 @@ <section name="Tomcat 7.0.29 (markt)"> <subsection name="Catalina"> <changelog> + <add> + Add support for searching for roles in JNDI/LDAP + using another value than the actual DN or username specified. + Rather it will use a value from the users directory entry. + The new attribute introduced to the JNDIRealm is userRoleAttribute + (fhanik) + </add> <fix> Fix checking of recommended tcnative library version when using the APR connector. (rjung) Modified: tomcat/tc7.0.x/trunk/webapps/docs/config/realm.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/config/realm.xml?rev=1355617&r1=1355616&r2=1355617&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/config/realm.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/config/realm.xml Sat Jun 30 01:08:37 2012 @@ -475,7 +475,9 @@ <p>The LDAP filter expression used for performing role searches. Use <code>{0}</code> to substitute the distinguished name (DN) of the user, and/or <code>{1}</code> to - substitute the username. If not specified a role search does + substitute the username, and/or <code>{2}</code> the value of the + userRoleAttribute attribute from the users directory entry. + If not specified a role search does not take place and roles are taken only from the attribute in the user's entry specified by the <code>userRoleName</code> property.</p> @@ -571,6 +573,18 @@ search.</p> </attribute> + <attribute name="userRoleAttribute" required="false"> + <p>The name of an attribute in the user's directory entry + containing the value that you wish to use when you search for + roles. This is especially useful for RFC 2307 where + the role memberUid can be the <code>uid</code> or the + <code>uidNumber</code> of the user. This value will be + marked as <code>{2}</code> in your role pattern. + This value will NOT be available for nested group searches, + where <code>{2}</code> will become <code>{1}</code> + </p> + </attribute> + <attribute name="userSearch" required="false"> <p>The LDAP filter expression to use when searching for a user's directory entry, with <code>{0}</code> marking where --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org