[jboss-cvs] JBossAS SVN: r74862 - branches/Branch_4_2/security/src/main/org/jboss/security/auth/spi.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu Jun 19 18:38:25 EDT 2008
Author: mmoyses
Date: 2008-06-19 18:38:25 -0400 (Thu, 19 Jun 2008)
New Revision: 74862
Modified:
branches/Branch_4_2/security/src/main/org/jboss/security/auth/spi/LdapLoginModule.java
Log:
JBAS-4343
Modified: branches/Branch_4_2/security/src/main/org/jboss/security/auth/spi/LdapLoginModule.java
===================================================================
--- branches/Branch_4_2/security/src/main/org/jboss/security/auth/spi/LdapLoginModule.java 2008-06-19 21:51:22 UTC (rev 74861)
+++ branches/Branch_4_2/security/src/main/org/jboss/security/auth/spi/LdapLoginModule.java 2008-06-19 22:38:25 UTC (rev 74862)
@@ -3,39 +3,40 @@
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
package org.jboss.security.auth.spi;
+import java.security.Principal;
import java.security.acl.Group;
-import java.security.Principal;
import java.util.Iterator;
+import java.util.Properties;
import java.util.Map.Entry;
-import java.util.Properties;
+
+import javax.management.ObjectName;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
+import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
-import javax.naming.directory.SearchControls;
import javax.naming.ldap.InitialLdapContext;
import javax.security.auth.login.LoginException;
-import javax.management.ObjectName;
import org.jboss.security.SimpleGroup;
@@ -60,7 +61,7 @@
* Additional module properties include:
* <ul>
* <li>principalDNPrefix, principalDNSuffix : A prefix and suffix to add to the
- * username when forming the user distiguished name. This is useful if you
+ * username when forming the user distinguished name. This is useful if you
* prompt a user for a username and you don't want them to have to enter the
* fully distinguished name. Using this property and principalDNSuffix the
* userDN will be formed as:
@@ -103,12 +104,12 @@
* If the `roleAttributeIsDN` property is set to false, this property is ignored.
* <li>java.naming.security.principal (4.0.3+): This standard JNDI property if
* specified in the login configuration, it is used to rebind to the ldap server
- * after user authentication for the role searches. This may be necessar if the
+ * after user authentication for the role searches. This may be necessary if the
* user does not have permission to perform these queres. If specified, the
* java.naming.security.credentials provides the rebind credentials.
* </li>
* <li>java.naming.security.credentials (4.0.3+): This standard JNDI property
- * if specified in the login configuration, it is used to rebind to the ldap
+ * if specified in the login configuration, it is used to rebind to the LDAP
* server after user authentication for the role searches along with the
* java.naming.security.principal value. This can be encrypted using the
* jaasSecurityDomain.
@@ -164,17 +165,27 @@
public class LdapLoginModule extends UsernamePasswordLoginModule
{
private static final String PRINCIPAL_DN_PREFIX_OPT = "principalDNPrefix";
+
private static final String PRINCIPAL_DN_SUFFIX_OPT = "principalDNSuffix";
+
private static final String ROLES_CTX_DN_OPT = "rolesCtxDN";
- private static final String USER_ROLES_CTX_DN_ATTRIBUTE_ID_OPT =
- "userRolesCtxDNAttributeName";
+
+ private static final String USER_ROLES_CTX_DN_ATTRIBUTE_ID_OPT = "userRolesCtxDNAttributeName";
+
private static final String UID_ATTRIBUTE_ID_OPT = "uidAttributeID";
+
private static final String ROLE_ATTRIBUTE_ID_OPT = "roleAttributeID";
+
private static final String MATCH_ON_USER_DN_OPT = "matchOnUserDN";
+
private static final String ROLE_ATTRIBUTE_IS_DN_OPT = "roleAttributeIsDN";
+
private static final String ROLE_NAME_ATTRIBUTE_ID_OPT = "roleNameAttributeID";
+
private static final String SEARCH_TIME_LIMIT_OPT = "searchTimeLimit";
+
private static final String SEARCH_SCOPE_OPT = "searchScope";
+
private static final String SECURITY_DOMAIN_OPT = "jaasSecurityDomain";
public LdapLoginModule()
@@ -183,7 +194,7 @@
private transient SimpleGroup userRoles = new SimpleGroup("Roles");
- /** Overriden to return an empty password string as typically one cannot
+ /** Overridden to return an empty password string as typically one cannot
obtain a user's password. We also override the validatePassword so
this is ok.
@return and empty password String
@@ -193,7 +204,7 @@
return "";
}
- /** Overriden by subclasses to return the Groups that correspond to the
+ /** Overridden by subclasses to return the Groups that correspond to the
to the role sets assigned to the user. Subclasses should create at
least a Group named "Roles" that contains the roles assigned to the user.
A second common group is "CallerPrincipal" that provides the application
@@ -214,6 +225,7 @@
*/
protected boolean validatePassword(String inputPassword, String expectedPassword)
{
+ boolean trace = log.isTraceEnabled();
boolean isValid = false;
if (inputPassword != null)
{
@@ -227,7 +239,8 @@
allowEmptyPasswords = Boolean.valueOf(flag).booleanValue();
if (allowEmptyPasswords == false)
{
- super.log.trace("Rejecting empty password due to allowEmptyPasswords");
+ if (trace)
+ log.trace("Rejecting empty password due to allowEmptyPasswords");
return false;
}
}
@@ -247,8 +260,8 @@
return isValid;
}
- private void createLdapInitContext(String username, Object credential)
- throws Exception
+ @SuppressWarnings("unchecked")
+ private void createLdapInitContext(String username, Object credential) throws Exception
{
boolean trace = log.isTraceEnabled();
Properties env = new Properties();
@@ -278,11 +291,11 @@
String bindDN = (String) options.get(Context.SECURITY_PRINCIPAL);
String bindCredential = (String) options.get(Context.SECURITY_CREDENTIALS);
String securityDomain = (String) options.get(SECURITY_DOMAIN_OPT);
- if( securityDomain != null )
+ if (securityDomain != null)
{
- ObjectName serviceName = new ObjectName(securityDomain);
- char[] tmp = DecodeAction.decode(bindCredential, serviceName);
- bindCredential = new String(tmp);
+ ObjectName serviceName = new ObjectName(securityDomain);
+ char[] tmp = DecodeAction.decode(bindCredential, serviceName);
+ bindCredential = new String(tmp);
}
String principalDNPrefix = (String) options.get(PRINCIPAL_DN_PREFIX_OPT);
@@ -297,183 +310,210 @@
env.setProperty(Context.PROVIDER_URL, providerURL);
env.setProperty(Context.SECURITY_PRINCIPAL, userDN);
env.put(Context.SECURITY_CREDENTIALS, credential);
- if( trace )
+ if (trace)
{
Properties tmp = new Properties();
tmp.putAll(env);
tmp.setProperty(Context.SECURITY_CREDENTIALS, "***");
- log.trace("Logging into LDAP server, env=" + tmp.toString());
+ if (trace)
+ log.trace("Logging into LDAP server, env=" + tmp.toString());
}
- InitialLdapContext ctx = new InitialLdapContext(env, null);
- if( trace )
- log.trace("Logged into LDAP server, " + ctx);
- if( bindDN != null )
+ InitialLdapContext ctx = null;
+ try
{
- // Rebind the ctx to the bind dn/credentials for the roles searches
- if( trace )
- log.trace("Rebind SECURITY_PRINCIPAL to: "+bindDN);
- env.setProperty(Context.SECURITY_PRINCIPAL, bindDN);
- env.put(Context.SECURITY_CREDENTIALS, bindCredential);
ctx = new InitialLdapContext(env, null);
- }
+ if (trace)
+ log.trace("Logged into LDAP server, " + ctx);
- /* If a userRolesCtxDNAttributeName was speocified, see if there is a
- user specific roles DN. If there is not, the default rolesCtxDN will
- be used.
- */
- String rolesCtxDN = (String) options.get(ROLES_CTX_DN_OPT);
- String userRolesCtxDNAttributeName = (String) options.get(USER_ROLES_CTX_DN_ATTRIBUTE_ID_OPT);
- if (userRolesCtxDNAttributeName != null)
- {
- // Query the indicated attribute for the roles ctx DN to use
- String[] returnAttribute = {userRolesCtxDNAttributeName};
- try
+ if (bindDN != null)
{
- Attributes result = ctx.getAttributes(userDN, returnAttribute);
- if (result.get(userRolesCtxDNAttributeName) != null)
- {
- rolesCtxDN = result.get(userRolesCtxDNAttributeName).get().toString();
- super.log.trace("Found user roles context DN: " + rolesCtxDN);
- }
+ // Rebind the ctx to the bind dn/credentials for the roles searches
+ if (trace)
+ log.trace("Rebind SECURITY_PRINCIPAL to: " + bindDN);
+ env.setProperty(Context.SECURITY_PRINCIPAL, bindDN);
+ env.put(Context.SECURITY_CREDENTIALS, bindCredential);
+ ctx = new InitialLdapContext(env, null);
}
- catch (NamingException e)
- {
- super.log.debug("Failed to query userRolesCtxDNAttributeName", e);
- }
- }
- // Search for any roles associated with the user
- if (rolesCtxDN != null)
- {
- String uidAttrName = (String) options.get(UID_ATTRIBUTE_ID_OPT);
- if (uidAttrName == null)
- uidAttrName = "uid";
- String roleAttrName = (String) options.get(ROLE_ATTRIBUTE_ID_OPT);
- if (roleAttrName == null)
- roleAttrName = "roles";
- StringBuffer roleFilter = new StringBuffer("(");
- roleFilter.append(uidAttrName);
- roleFilter.append("={0})");
- String userToMatch = username;
- if (matchOnUserDN == true)
- userToMatch = userDN;
-
- String[] roleAttr = {roleAttrName};
- // Is user's role attribute a DN or the role name
- String roleAttributeIsDNOption = (String) options.get(ROLE_ATTRIBUTE_IS_DN_OPT);
- boolean roleAttributeIsDN = Boolean.valueOf(roleAttributeIsDNOption).booleanValue();
-
- // If user's role attribute is a DN, what is the role's name attribute
- // Default to 'name' (Group name attribute in Active Directory)
- String roleNameAttributeID = (String) options.get(ROLE_NAME_ATTRIBUTE_ID_OPT);
- if (roleNameAttributeID == null)
- roleNameAttributeID = "name";
-
- int searchScope = SearchControls.SUBTREE_SCOPE;
- int searchTimeLimit = 10000;
- String timeLimit = (String) options.get(SEARCH_TIME_LIMIT_OPT);
- if( timeLimit != null )
+ /* If a userRolesCtxDNAttributeName was speocified, see if there is a
+ user specific roles DN. If there is not, the default rolesCtxDN will
+ be used.
+ */
+ String rolesCtxDN = (String) options.get(ROLES_CTX_DN_OPT);
+ String userRolesCtxDNAttributeName = (String) options.get(USER_ROLES_CTX_DN_ATTRIBUTE_ID_OPT);
+ if (userRolesCtxDNAttributeName != null)
{
+ // Query the indicated attribute for the roles ctx DN to use
+ String[] returnAttribute = {userRolesCtxDNAttributeName};
try
{
- searchTimeLimit = Integer.parseInt(timeLimit);
+ Attributes result = ctx.getAttributes(userDN, returnAttribute);
+ if (result.get(userRolesCtxDNAttributeName) != null)
+ {
+ rolesCtxDN = result.get(userRolesCtxDNAttributeName).get().toString();
+ if (trace)
+ log.trace("Found user roles context DN: " + rolesCtxDN);
+ }
}
- catch(NumberFormatException e)
+ catch (NamingException e)
{
- log.trace("Failed to parse: "+timeLimit+", using searchTimeLimit="+searchTimeLimit);
+ if (trace)
+ log.debug("Failed to query userRolesCtxDNAttributeName", e);
}
}
- String scope = (String) options.get(SEARCH_SCOPE_OPT);
- if( "OBJECT_SCOPE".equalsIgnoreCase(scope) )
- searchScope = SearchControls.OBJECT_SCOPE;
- else if( "ONELEVEL_SCOPE".equalsIgnoreCase(scope) )
- searchScope = SearchControls.ONELEVEL_SCOPE;
- if( "SUBTREE_SCOPE".equalsIgnoreCase(scope) )
- searchScope = SearchControls.SUBTREE_SCOPE;
- try
+ // Search for any roles associated with the user
+ if (rolesCtxDN != null)
{
- SearchControls controls = new SearchControls();
- controls.setSearchScope(searchScope);
- controls.setReturningAttributes(roleAttr);
- controls.setTimeLimit(searchTimeLimit);
- Object[] filterArgs = {userToMatch};
- if( trace )
+ String uidAttrName = (String) options.get(UID_ATTRIBUTE_ID_OPT);
+ if (uidAttrName == null)
+ uidAttrName = "uid";
+ String roleAttrName = (String) options.get(ROLE_ATTRIBUTE_ID_OPT);
+ if (roleAttrName == null)
+ roleAttrName = "roles";
+ StringBuffer roleFilter = new StringBuffer("(");
+ roleFilter.append(uidAttrName);
+ roleFilter.append("={0})");
+ String userToMatch = username;
+ if (matchOnUserDN == true)
+ userToMatch = userDN;
+
+ String[] roleAttr = {roleAttrName};
+ // Is user's role attribute a DN or the role name
+ String roleAttributeIsDNOption = (String) options.get(ROLE_ATTRIBUTE_IS_DN_OPT);
+ boolean roleAttributeIsDN = Boolean.valueOf(roleAttributeIsDNOption).booleanValue();
+
+ // If user's role attribute is a DN, what is the role's name attribute
+ // Default to 'name' (Group name attribute in Active Directory)
+ String roleNameAttributeID = (String) options.get(ROLE_NAME_ATTRIBUTE_ID_OPT);
+ if (roleNameAttributeID == null)
+ roleNameAttributeID = "name";
+
+ int searchScope = SearchControls.SUBTREE_SCOPE;
+ int searchTimeLimit = 10000;
+ String timeLimit = (String) options.get(SEARCH_TIME_LIMIT_OPT);
+ if (timeLimit != null)
{
- log.trace("searching rolesCtxDN="+rolesCtxDN+", roleFilter="+roleFilter
- +", filterArgs="+userToMatch+", roleAttr="+roleAttr
- +", searchScope="+searchScope+", searchTimeLimit="+searchTimeLimit
- );
+ try
+ {
+ searchTimeLimit = Integer.parseInt(timeLimit);
+ }
+ catch (NumberFormatException e)
+ {
+ if (trace)
+ log.trace("Failed to parse: " + timeLimit + ", using searchTimeLimit=" + searchTimeLimit);
+ }
}
- NamingEnumeration answer = ctx.search(rolesCtxDN, roleFilter.toString(),
- filterArgs, controls);
- while (answer.hasMore())
+ String scope = (String) options.get(SEARCH_SCOPE_OPT);
+ if ("OBJECT_SCOPE".equalsIgnoreCase(scope))
+ searchScope = SearchControls.OBJECT_SCOPE;
+ else if ("ONELEVEL_SCOPE".equalsIgnoreCase(scope))
+ searchScope = SearchControls.ONELEVEL_SCOPE;
+ if ("SUBTREE_SCOPE".equalsIgnoreCase(scope))
+ searchScope = SearchControls.SUBTREE_SCOPE;
+
+ NamingEnumeration answer = null;
+ try
{
- SearchResult sr = (SearchResult) answer.next();
- if( trace )
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope(searchScope);
+ controls.setReturningAttributes(roleAttr);
+ controls.setTimeLimit(searchTimeLimit);
+ Object[] filterArgs = {userToMatch};
+ if (trace)
{
- log.trace("Checking answer: "+sr.getName());
+ log.trace("searching rolesCtxDN=" + rolesCtxDN + ", roleFilter=" + roleFilter + ", filterArgs="
+ + userToMatch + ", roleAttr=" + roleAttr + ", searchScope=" + searchScope
+ + ", searchTimeLimit=" + searchTimeLimit);
}
- Attributes attrs = sr.getAttributes();
- Attribute roles = attrs.get(roleAttrName);
- for (int r = 0; r < roles.size(); r++)
+ answer = ctx.search(rolesCtxDN, roleFilter.toString(), filterArgs, controls);
+ while (answer.hasMore())
{
- Object value = roles.get(r);
- String roleName = null;
- if (roleAttributeIsDN == true)
+ SearchResult sr = (SearchResult) answer.next();
+ if (trace)
{
- // Query the roleDN location for the value of roleNameAttributeID
- String roleDN = value.toString();
- String[] returnAttribute = {roleNameAttributeID};
- if( trace )
- log.trace("Following roleDN: " + roleDN);
- try
+ log.trace("Checking answer: " + sr.getName());
+ }
+ Attributes attrs = sr.getAttributes();
+ Attribute roles = attrs.get(roleAttrName);
+ if (roles != null)
+ {
+ for (int r = 0; r < roles.size(); r++)
{
- Attributes result2 = ctx.getAttributes(roleDN, returnAttribute);
- Attribute roles2 = result2.get(roleNameAttributeID);
- if( roles2 != null )
+ Object value = roles.get(r);
+ String roleName = null;
+ if (roleAttributeIsDN == true)
{
- for(int m = 0; m < roles2.size(); m ++)
+ // Query the roleDN location for the value of roleNameAttributeID
+ String roleDN = value.toString();
+ String[] returnAttribute = {roleNameAttributeID};
+ if (trace)
+ log.trace("Following roleDN: " + roleDN);
+ try
{
- roleName = (String) roles2.get(m);
- addRole(roleName);
+ Attributes result2 = ctx.getAttributes(roleDN, returnAttribute);
+ Attribute roles2 = result2.get(roleNameAttributeID);
+ if (roles2 != null)
+ {
+ for (int m = 0; m < roles2.size(); m++)
+ {
+ roleName = (String) roles2.get(m);
+ addRole(roleName);
+ }
+ }
}
+ catch (NamingException e)
+ {
+ if (trace)
+ log.trace("Failed to query roleNameAttrName", e);
+ }
}
+ else
+ {
+ // The role attribute value is the role name
+ roleName = value.toString();
+ addRole(roleName);
+ }
}
- catch (NamingException e)
- {
- log.trace("Failed to query roleNameAttrName", e);
- }
}
else
{
- // The role attribute value is the role name
- roleName = value.toString();
- addRole(roleName);
+ if (trace)
+ log.trace("No attribute " + roleAttrName + " found. No roles mapped");
}
}
}
- answer.close();
+ catch (NamingException e)
+ {
+ if (trace)
+ log.trace("Failed to locate roles", e);
+ }
+ finally
+ {
+ if (answer != null)
+ answer.close();
+ }
}
- catch (NamingException e)
- {
- if( trace )
- log.trace("Failed to locate roles", e);
- }
}
- // Close the context to release the connection
- ctx.close();
+ finally
+ {
+ // Close the context to release the connection
+ if (ctx != null)
+ ctx.close();
+ }
}
private void addRole(String roleName)
{
+ boolean trace = log.isTraceEnabled();
if (roleName != null)
{
try
{
Principal p = super.createIdentity(roleName);
- log.trace("Assign user to role " + roleName);
+ if (trace)
+ log.trace("Assign user to role " + roleName);
userRoles.addMember(p);
}
catch (Exception e)
More information about the jboss-cvs-commits
mailing list