User: starksm 
  Date: 01/08/03 13:29:03

  Modified:    src/main/org/jboss/security/auth/spi LdapLoginModule.java
  Log:
  Fix bug in validatePassword
  
  Revision  Changes    Path
  1.3       +221 -220  
jbosssx/src/main/org/jboss/security/auth/spi/LdapLoginModule.java
  
  Index: LdapLoginModule.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/jbosssx/src/main/org/jboss/security/auth/spi/LdapLoginModule.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- LdapLoginModule.java      2001/07/09 19:57:53     1.2
  +++ LdapLoginModule.java      2001/08/03 20:29:03     1.3
  @@ -1,220 +1,221 @@
  -/*
  - * JBoss, the OpenSource EJB server
  - *
  - * Distributable under LGPL license.
  - * See terms of license at gnu.org.
  - */
  -package org.jboss.security.auth.spi;
  -
  -import java.security.Principal;
  -import java.security.acl.Group;
  -import java.util.ArrayList;
  -import java.util.Iterator;
  -import java.util.Map;
  -import java.util.Map.Entry;
  -import java.util.Properties;
  -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.BasicAttributes;
  -import javax.naming.directory.SearchResult;
  -import javax.naming.ldap.InitialLdapContext;
  -import javax.security.auth.Subject;
  -import javax.security.auth.callback.Callback;
  -import javax.security.auth.callback.CallbackHandler;
  -import javax.security.auth.callback.NameCallback;
  -import javax.security.auth.callback.PasswordCallback;
  -import javax.security.auth.callback.UnsupportedCallbackException;
  -import javax.security.auth.login.FailedLoginException;
  -import javax.security.auth.login.LoginException;
  -import javax.security.auth.spi.LoginModule;
  -
  -import org.jboss.security.SimpleGroup;
  -import org.jboss.security.SimplePrincipal;
  -import org.jboss.security.auth.callback.ObjectCallback;
  -import org.jboss.security.auth.spi.UsernamePasswordLoginModule;
  -
  -/** An implementation of LoginModule that authenticates against an LDAP server
  - using JNDI based on the configuration properties.
  - 
  - The LoginModule options include whatever options your LDAP JNDI provider
  - support. Examples of standard property names are:
  - Context.INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial"
  - Context.SECURITY_PROTOCOL = "java.naming.security.protocol"
  - Context.PROVIDER_URL = "java.naming.provider.url"
  - Context.SECURITY_AUTHENTICATION = "java.naming.security.authentication"
  - 
  - The Context.SECURITY_PRINCIPAL is set to the distinguished name of the user
  - as obtained by the callback handler and the Context.SECURITY_CREDENTIALS
  - property is either set to the String password or Object credential depending
  - on the useObjectCredential option.
  - 
  - Additional module properties include:
  - principalDNPrefix, principalDNSuffix : A prefix and suffix to add to the
  - username when forming the user distiguished 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:
  - <code>String userDN = principalDNPrefix + username + principalDNSuffix;</code>
  - 
  - useObjectCredential : indicates that the credential should be obtained as
  - an opaque Object using the org.jboss.security.plugins.ObjectCallback type
  - of Callback rather than as a char[] password using a JAAS PasswordCallback.
  - 
  - rolesCtxDN : The distinguished name to the context to search for user roles.
  - roleAttributeName : The name of the attribute that contains the user roles
  - uidAttributeName : The name of the attribute that in the object containing
  - the user roles that corresponds to the userid. This is used to locate the
  - user roles.
  - 
  - A sample login config:
  - testLdap {
  - org.jboss.security.plugins.samples.LdapLoginModule required
  - java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
  - principalDNPrefix=uid=
  - uidAttributeID=userid
  - roleAttributeID=rolenames
  - principalDNSuffix=,ou=People,o=displayscape.com
  - rolesCtxDN=ou=Users,cn=Project1,ou=Projects,o=displayscape.com
  - java.naming.provider.url=ldap://siren-int/
  - java.naming.security.authentication=simple
  - };
  - 
  - @author [EMAIL PROTECTED]
  - @version $Revision: 1.2 $
  - */
  -public class LdapLoginModule extends UsernamePasswordLoginModule
  -{
  -   private static final String USE_OBJECT_CREDENTIAL_OPT = "useObjectCredential";
  -   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 UID_ATTRIBUTE_ID_OPT = "uidAttributeID";
  -   private static final String ROLE_ATTRIBUTE_ID_OPT = "roleAttributeID";
  -   
  -   public LdapLoginModule()
  -   {
  -   }
  -   
  -   private transient SimpleGroup userRoles = new SimpleGroup("Roles");
  -   
  -   /** Overriden 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
  -    */
  -   protected String getUsersPassword() throws LoginException
  -   {
  -      return "";
  -   }
  -   /** Overriden 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 rather than the security domain identity.
  -   @return Group[] containing the sets of roles 
  -   */
  -   protected Group[] getRoleSets() throws LoginException
  -   {
  -      Group[] roleSets = {userRoles};
  -      return roleSets;
  -   }
  -
  -   protected boolean validatePassword(String inputPassword, String expectedPassword)
  -   {
  -      boolean isValid = false;
  -      if( inputPassword != null )
  -      {
  -         try
  -         {
  -            // Validate the password by trying to create an initial context
  -            String username = getUsername();
  -            createLdapInitContext(username, inputPassword);
  -         }
  -         catch(NamingException e)
  -         {
  -            e.printStackTrace();
  -         }
  -      }
  -      return isValid;
  -   }
  -   
  -   private void createLdapInitContext(String username, Object credential) throws 
NamingException
  -   {
  -      Properties env = new Properties();
  -      // Map all option into the JNDI InitialLdapContext env
  -      Iterator iter = options.entrySet().iterator();
  -      while( iter.hasNext() )
  -      {
  -         Entry entry = (Entry) iter.next();
  -         env.put(entry.getKey(), entry.getValue());
  -      }
  -      
  -      // Set defaults for key values if they are missing
  -      String factoryName = env.getProperty(Context.INITIAL_CONTEXT_FACTORY);
  -      if( factoryName == null )
  -      {
  -         factoryName = "com.sun.jndi.ldap.LdapCtxFactory";
  -         env.setProperty(Context.INITIAL_CONTEXT_FACTORY, factoryName);
  -      }
  -      String authType = env.getProperty(Context.SECURITY_AUTHENTICATION);
  -      if( authType == null )
  -         env.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
  -      String protocol = env.getProperty(Context.SECURITY_PROTOCOL);
  -      String providerURL = (String) options.get(Context.PROVIDER_URL);
  -      if( providerURL == null )
  -         providerURL = "ldap://localhost:"; + ((protocol != null && 
protocol.equals("ssl")) ? "389" : "636");
  -
  -      String principalDNPrefix = (String) options.get(PRINCIPAL_DN_PREFIX_OPT);
  -      if( principalDNPrefix == null )
  -         principalDNPrefix="";
  -      String principalDNSuffix = (String) options.get(PRINCIPAL_DN_SUFFIX_OPT);
  -      if( principalDNSuffix == null )
  -         principalDNSuffix="";
  -      String userDN = principalDNPrefix + username + principalDNSuffix;
  -      env.setProperty(Context.PROVIDER_URL, providerURL);
  -      env.setProperty(Context.SECURITY_PRINCIPAL, userDN);
  -      env.put(Context.SECURITY_CREDENTIALS, credential);
  -      System.out.println("Logging into LDAP server, env="+env);
  -      InitialLdapContext ctx = new InitialLdapContext(env, null);
  -      System.out.println("Logged into LDAP server, "+ctx);
  -      // Query the user's roles...
  -      String rolesCtxDN = (String) options.get(ROLES_CTX_DN_OPT);
  -      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";
  -         BasicAttributes matchAttrs = new BasicAttributes(true);
  -         matchAttrs.put(uidAttrName, username);
  -         String[] roleAttr =
  -         {roleAttrName};
  -         try
  -         {
  -            NamingEnumeration answer = ctx.search(rolesCtxDN, matchAttrs, roleAttr);
  -            while( answer.hasMore() )
  -            {
  -               SearchResult sr = (SearchResult) answer.next();
  -               Attributes attrs = sr.getAttributes();
  -               Attribute roles = attrs.get(roleAttrName);
  -               for(int r = 0; r < roles.size(); r ++)
  -               {
  -                  Object value = roles.get(r);
  -                  String roleName = value.toString();
  -                  userRoles.addMember(new SimplePrincipal(roleName));
  -               }
  -            }
  -         }
  -         catch(NamingException e)
  -         {
  -         }
  -      }
  -      // Close the context to release the connection
  -      ctx.close();
  -   }
  -}
  +/*
  + * JBoss, the OpenSource EJB server
  + *
  + * Distributable under LGPL license.
  + * See terms of license at gnu.org.
  + */
  +package org.jboss.security.auth.spi;
  +
  +import java.security.Principal;
  +import java.security.acl.Group;
  +import java.util.ArrayList;
  +import java.util.Iterator;
  +import java.util.Map;
  +import java.util.Map.Entry;
  +import java.util.Properties;
  +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.BasicAttributes;
  +import javax.naming.directory.SearchResult;
  +import javax.naming.ldap.InitialLdapContext;
  +import javax.security.auth.Subject;
  +import javax.security.auth.callback.Callback;
  +import javax.security.auth.callback.CallbackHandler;
  +import javax.security.auth.callback.NameCallback;
  +import javax.security.auth.callback.PasswordCallback;
  +import javax.security.auth.callback.UnsupportedCallbackException;
  +import javax.security.auth.login.FailedLoginException;
  +import javax.security.auth.login.LoginException;
  +import javax.security.auth.spi.LoginModule;
  +
  +import org.jboss.security.SimpleGroup;
  +import org.jboss.security.SimplePrincipal;
  +import org.jboss.security.auth.callback.ObjectCallback;
  +import org.jboss.security.auth.spi.UsernamePasswordLoginModule;
  +
  +/** An implementation of LoginModule that authenticates against an LDAP server
  + using JNDI based on the configuration properties.
  + 
  + The LoginModule options include whatever options your LDAP JNDI provider
  + support. Examples of standard property names are:
  + Context.INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial"
  + Context.SECURITY_PROTOCOL = "java.naming.security.protocol"
  + Context.PROVIDER_URL = "java.naming.provider.url"
  + Context.SECURITY_AUTHENTICATION = "java.naming.security.authentication"
  + 
  + The Context.SECURITY_PRINCIPAL is set to the distinguished name of the user
  + as obtained by the callback handler and the Context.SECURITY_CREDENTIALS
  + property is either set to the String password or Object credential depending
  + on the useObjectCredential option.
  + 
  + Additional module properties include:
  + principalDNPrefix, principalDNSuffix : A prefix and suffix to add to the
  + username when forming the user distiguished 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:
  + <code>String userDN = principalDNPrefix + username + principalDNSuffix;</code>
  + 
  + useObjectCredential : indicates that the credential should be obtained as
  + an opaque Object using the org.jboss.security.plugins.ObjectCallback type
  + of Callback rather than as a char[] password using a JAAS PasswordCallback.
  + 
  + rolesCtxDN : The distinguished name to the context to search for user roles.
  + roleAttributeName : The name of the attribute that contains the user roles
  + uidAttributeName : The name of the attribute that in the object containing
  + the user roles that corresponds to the userid. This is used to locate the
  + user roles.
  + 
  + A sample login config:
  + testLdap {
  + org.jboss.security.plugins.samples.LdapLoginModule required
  + java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
  + principalDNPrefix=uid=
  + uidAttributeID=userid
  + roleAttributeID=rolenames
  + principalDNSuffix=,ou=People,o=displayscape.com
  + rolesCtxDN=ou=Users,cn=Project1,ou=Projects,o=displayscape.com
  + java.naming.provider.url=ldap://siren-int/
  + java.naming.security.authentication=simple
  + };
  + 
  + @author [EMAIL PROTECTED]
  + @version $Revision: 1.3 $
  + */
  +public class LdapLoginModule extends UsernamePasswordLoginModule
  +{
  +   private static final String USE_OBJECT_CREDENTIAL_OPT = "useObjectCredential";
  +   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 UID_ATTRIBUTE_ID_OPT = "uidAttributeID";
  +   private static final String ROLE_ATTRIBUTE_ID_OPT = "roleAttributeID";
  +   
  +   public LdapLoginModule()
  +   {
  +   }
  +   
  +   private transient SimpleGroup userRoles = new SimpleGroup("Roles");
  +   
  +   /** Overriden 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
  +    */
  +   protected String getUsersPassword() throws LoginException
  +   {
  +      return "";
  +   }
  +   /** Overriden 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 rather than the security domain identity.
  +   @return Group[] containing the sets of roles 
  +   */
  +   protected Group[] getRoleSets() throws LoginException
  +   {
  +      Group[] roleSets = {userRoles};
  +      return roleSets;
  +   }
  +
  +   protected boolean validatePassword(String inputPassword, String expectedPassword)
  +   {
  +      boolean isValid = false;
  +      if( inputPassword != null )
  +      {
  +         try
  +         {
  +            // Validate the password by trying to create an initial context
  +            String username = getUsername();
  +            createLdapInitContext(username, inputPassword);
  +            isValid = true;
  +         }
  +         catch(NamingException e)
  +         {
  +            e.printStackTrace();
  +         }
  +      }
  +      return isValid;
  +   }
  +   
  +   private void createLdapInitContext(String username, Object credential) throws 
NamingException
  +   {
  +      Properties env = new Properties();
  +      // Map all option into the JNDI InitialLdapContext env
  +      Iterator iter = options.entrySet().iterator();
  +      while( iter.hasNext() )
  +      {
  +         Entry entry = (Entry) iter.next();
  +         env.put(entry.getKey(), entry.getValue());
  +      }
  +      
  +      // Set defaults for key values if they are missing
  +      String factoryName = env.getProperty(Context.INITIAL_CONTEXT_FACTORY);
  +      if( factoryName == null )
  +      {
  +         factoryName = "com.sun.jndi.ldap.LdapCtxFactory";
  +         env.setProperty(Context.INITIAL_CONTEXT_FACTORY, factoryName);
  +      }
  +      String authType = env.getProperty(Context.SECURITY_AUTHENTICATION);
  +      if( authType == null )
  +         env.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
  +      String protocol = env.getProperty(Context.SECURITY_PROTOCOL);
  +      String providerURL = (String) options.get(Context.PROVIDER_URL);
  +      if( providerURL == null )
  +         providerURL = "ldap://localhost:"; + ((protocol != null && 
protocol.equals("ssl")) ? "389" : "636");
  +
  +      String principalDNPrefix = (String) options.get(PRINCIPAL_DN_PREFIX_OPT);
  +      if( principalDNPrefix == null )
  +         principalDNPrefix="";
  +      String principalDNSuffix = (String) options.get(PRINCIPAL_DN_SUFFIX_OPT);
  +      if( principalDNSuffix == null )
  +         principalDNSuffix="";
  +      String userDN = principalDNPrefix + username + principalDNSuffix;
  +      env.setProperty(Context.PROVIDER_URL, providerURL);
  +      env.setProperty(Context.SECURITY_PRINCIPAL, userDN);
  +      env.put(Context.SECURITY_CREDENTIALS, credential);
  +      System.out.println("Logging into LDAP server, env="+env);
  +      InitialLdapContext ctx = new InitialLdapContext(env, null);
  +      System.out.println("Logged into LDAP server, "+ctx);
  +      // Query the user's roles...
  +      String rolesCtxDN = (String) options.get(ROLES_CTX_DN_OPT);
  +      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";
  +         BasicAttributes matchAttrs = new BasicAttributes(true);
  +         matchAttrs.put(uidAttrName, username);
  +         String[] roleAttr =
  +         {roleAttrName};
  +         try
  +         {
  +            NamingEnumeration answer = ctx.search(rolesCtxDN, matchAttrs, roleAttr);
  +            while( answer.hasMore() )
  +            {
  +               SearchResult sr = (SearchResult) answer.next();
  +               Attributes attrs = sr.getAttributes();
  +               Attribute roles = attrs.get(roleAttrName);
  +               for(int r = 0; r < roles.size(); r ++)
  +               {
  +                  Object value = roles.get(r);
  +                  String roleName = value.toString();
  +                  userRoles.addMember(new SimplePrincipal(roleName));
  +               }
  +            }
  +         }
  +         catch(NamingException e)
  +         {
  +         }
  +      }
  +      // Close the context to release the connection
  +      ctx.close();
  +   }
  +}
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to