[jboss-cvs] JBossAS SVN: r74644 - projects/security/security-jboss-sx/trunk/jbosssx/src/main/org/jboss/security/auth/spi.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Jun 16 17:40:07 EDT 2008


Author: mmoyses
Date: 2008-06-16 17:40:07 -0400 (Mon, 16 Jun 2008)
New Revision: 74644

Modified:
   projects/security/security-jboss-sx/trunk/jbosssx/src/main/org/jboss/security/auth/spi/LdapExtLoginModule.java
Log:
SECURITY-225: maps roles when authentication was skipped by userFirstPass

Modified: projects/security/security-jboss-sx/trunk/jbosssx/src/main/org/jboss/security/auth/spi/LdapExtLoginModule.java
===================================================================
--- projects/security/security-jboss-sx/trunk/jbosssx/src/main/org/jboss/security/auth/spi/LdapExtLoginModule.java	2008-06-16 21:07:51 UTC (rev 74643)
+++ projects/security/security-jboss-sx/trunk/jbosssx/src/main/org/jboss/security/auth/spi/LdapExtLoginModule.java	2008-06-16 21:40:07 UTC (rev 74644)
@@ -138,34 +138,61 @@
 public class LdapExtLoginModule extends UsernamePasswordLoginModule
 {
    private static final String ROLES_CTX_DN_OPT = "rolesCtxDN";
+
    private static final String ROLE_ATTRIBUTE_ID_OPT = "roleAttributeID";
+
    private static final String ROLE_ATTRIBUTE_IS_DN_OPT = "roleAttributeIsDN";
+
    private static final String ROLE_NAME_ATTRIBUTE_ID_OPT = "roleNameAttributeID";
 
    private static final String BIND_DN = "bindDN";
+
    private static final String BIND_CREDENTIAL = "bindCredential";
+
    private static final String BASE_CTX_DN = "baseCtxDN";
+
    private static final String BASE_FILTER_OPT = "baseFilter";
+
    private static final String ROLE_FILTER_OPT = "roleFilter";
+
    private static final String ROLE_RECURSION = "roleRecursion";
+
    private static final String DEFAULT_ROLE = "defaultRole";
+
    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";
 
    protected String bindDN;
+
    protected String bindCredential;
+
    protected String baseDN;
+
    protected String baseFilter;
+
    protected String rolesCtxDN;
+
    protected String roleFilter;
+
    protected String roleAttributeID;
+
    protected String roleNameAttributeID;
+
    protected boolean roleAttributeIsDN;
+
    protected int recursion = 0;
+
    protected int searchTimeLimit = 10000;
+
    protected int searchScope = SearchControls.SUBTREE_SCOPE;
+
    protected boolean trace;
+   
+   // simple flag to indicate is the validatePassword method was called
+   protected boolean isPasswordValidated = false;
 
    public LdapExtLoginModule()
    {
@@ -174,7 +201,7 @@
    private transient SimpleGroup userRoles = new SimpleGroup("Roles");
 
    /**
-    Overriden to return an empty password string as typically one cannot obtain a
+    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
     */
@@ -184,7 +211,7 @@
    }
 
    /**
-    Overriden by subclasses to return the Groups that correspond to the 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 identity of the user
@@ -193,18 +220,37 @@
     */
    protected Group[] getRoleSets() throws LoginException
    {
+      // SECURITY-225: check if authentication was already done in a previous login module
+      // and perform role mapping
+      if (!isPasswordValidated)
+      {
+         try
+         {
+            String username = getUsername();
+            createLdapInitContext(username, null);
+            defaultRole();
+         }
+         catch (Exception e)
+         {
+            LoginException le = new LoginException();
+            le.initCause(e);
+            throw le;
+         }
+      }
+
       Group[] roleSets = {userRoles};
       return roleSets;
    }
 
    /**
-    Validate the inputPassword by creating a ldap InitialContext with the
+    Validate the inputPassword by creating a LDAP InitialContext with the
     SECURITY_CREDENTIALS set to the password.
     @param inputPassword the password to validate.
     @param expectedPassword ignored
     */
    protected boolean validatePassword(String inputPassword, String expectedPassword)
    {
+      isPasswordValidated = true;
       boolean isValid = false;
       if (inputPassword != null)
       {
@@ -262,15 +308,14 @@
    }
 
    /**
-    Bind to the ldap server for authentication. 
+    Bind to the LDAP server for authentication. 
     
     @param username
     @param credential
     @return true if the bind for authentication succeeded
     @throws NamingException
     */
-   private boolean createLdapInitContext(String username, Object credential)
-      throws Exception
+   private boolean createLdapInitContext(String username, Object credential) throws Exception
    {
       bindDN = (String) options.get(BIND_DN);
       bindCredential = (String) options.get(BIND_CREDENTIAL);
@@ -345,7 +390,7 @@
       }
       finally
       {
-         if( ctx != null )
+         if (ctx != null)
             ctx.close();
       }
       return true;
@@ -361,9 +406,8 @@
     @throws NamingException
     */
    @SuppressWarnings("unchecked")
-   protected String bindDNAuthentication(InitialLdapContext ctx,
-      String user, Object credential, String baseDN, String filter)
-      throws NamingException
+   protected String bindDNAuthentication(InitialLdapContext ctx, String user, Object credential, String baseDN,
+         String filter) throws NamingException
    {
       SearchControls constraints = new SearchControls();
       constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
@@ -376,7 +420,7 @@
       results = ctx.search(baseDN, filter, filterArgs, constraints);
       if (results.hasMore() == false)
       {
-       results.close();
+         results.close();
          throw new NamingException("Search of baseDN(" + baseDN + ") found no matches");
       }
 
@@ -390,9 +434,13 @@
 
       results.close();
       results = null;
-      // Bind as the user dn to authenticate the user
-      InitialLdapContext userCtx = constructInitialLdapContext(userDN, credential);
-      userCtx.close();
+      // SECURITY-225: don't need to authenticate again
+      if (isPasswordValidated)
+      {
+         // Bind as the user dn to authenticate the user
+         InitialLdapContext userCtx = constructInitialLdapContext(userDN, credential);
+         userCtx.close();
+      }
 
       return userDN;
    }
@@ -407,9 +455,8 @@
     @throws NamingException
     */
    @SuppressWarnings("unchecked")
-   protected void rolesSearch(InitialLdapContext ctx, SearchControls constraints,
-      String user, String userDN, int recursionMax, int nesting)
-      throws NamingException
+   protected void rolesSearch(InitialLdapContext ctx, SearchControls constraints, String user, String userDN,
+         int recursionMax, int nesting) throws NamingException
    {
       Object[] filterArgs = {user, userDN};
       NamingEnumeration results = ctx.search(rolesCtxDN, roleFilter, filterArgs, constraints);
@@ -419,15 +466,15 @@
          {
             SearchResult sr = (SearchResult) results.next();
             String dn = canonicalize(sr.getName());
-            if( nesting == 0 && roleAttributeIsDN && roleNameAttributeID != null )
+            if (nesting == 0 && roleAttributeIsDN && roleNameAttributeID != null)
             {
                // Check the top context for role names
                String[] attrNames = {roleNameAttributeID};
                Attributes result2 = ctx.getAttributes(dn, attrNames);
                Attribute roles2 = result2.get(roleNameAttributeID);
-               if( roles2 != null )
+               if (roles2 != null)
                {
-                  for(int m = 0; m < roles2.size(); m ++)
+                  for (int m = 0; m < roles2.size(); m++)
                   {
                      String roleName = (String) roles2.get(m);
                      addRole(roleName);
@@ -438,10 +485,10 @@
             // Query the context for the roleDN values
             String[] attrNames = {roleAttributeID};
             Attributes result = ctx.getAttributes(dn, attrNames);
-            if( result != null && result.size() > 0 )
+            if (result != null && result.size() > 0)
             {
                Attribute roles = result.get(roleAttributeID);
-               for (int n = 0; n < roles.size(); n ++)
+               for (int n = 0; n < roles.size(); n++)
                {
                   String roleName = (String) roles.get(n);
                   if (roleAttributeIsDN)
@@ -454,9 +501,9 @@
                      {
                         Attributes result2 = ctx.getAttributes(roleDN, returnAttribute);
                         Attribute roles2 = result2.get(roleNameAttributeID);
-                        if( roles2 != null )
+                        if (roles2 != null)
                         {
-                           for(int m = 0; m < roles2.size(); m ++)
+                           for (int m = 0; m < roles2.size(); m++)
                            {
                               roleName = (String) roles2.get(m);
                               addRole(roleName);
@@ -475,18 +522,17 @@
                   }
                }
             }
-   
+
             if (nesting < recursionMax)
             {
-               rolesSearch(ctx, constraints, user, dn,
-                  recursionMax, nesting + 1);
+               rolesSearch(ctx, constraints, user, dn, recursionMax, nesting + 1);
             }
          }
       }
       finally
       {
-        if( results != null )
-           results.close();
+         if (results != null)
+            results.close();
       }
 
    }
@@ -523,36 +569,35 @@
          env.setProperty(Context.SECURITY_PRINCIPAL, dn);
       if (credential != null)
          env.put(Context.SECURITY_CREDENTIALS, credential);
-      traceLdapEnv(env); 
+      traceLdapEnv(env);
       return new InitialLdapContext(env, null);
    }
-   
+
    private void traceLdapEnv(Properties env)
    {
-      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()); 
+         log.trace("Logging into LDAP server, env=" + tmp.toString());
       }
-   } 
-   
+   }
+
    //JBAS-3438 : Handle "/" correctly
    private String canonicalize(String searchResult)
    {
       String result = searchResult;
       int len = searchResult.length();
-      
+
       if (searchResult.endsWith("\""))
       {
-         result = searchResult.substring(0,len - 1) 
-                            + "," + rolesCtxDN + "\"";
+         result = searchResult.substring(0, len - 1) + "," + rolesCtxDN + "\"";
       }
       else
       {
          result = searchResult + "," + rolesCtxDN;
-       }
+      }
       return result;
    }
 




More information about the jboss-cvs-commits mailing list