[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