1 Reply Latest reply on Feb 12, 2008 11:57 AM by Ragav Gomatam

    Custom Login Module not working

    Vinicius Carvalho Apprentice

      Hello there! I've remember doing this before (4.0.1 version) and was pretty easy, as explained here:
      http://wiki.jboss.org/wiki/Wiki.jsp?page=CreatingACustomLoginModule

      I've followed all the steps (basically almost copied and pasted the code, replacing only the encode algorithm for password), but my module never calls the convertRawPassword method. Is there anything else needed?
      It does call the class constructor but nothing else.

      Regards

        • 1. Re: Custom Login Module not working
          Ragav Gomatam Novice

          I have posted the code of the DatabaseServerLogin Module.....Your method should be called from within getUsersPassword()...Check the super class code

          DatabaseServerLoginModule.java

          /*
          
           * JBoss, the OpenSource WebOS
          
           *
          
           * Distributable under LGPL license.
          
           * See terms of license at gnu.org.
          
           */
          
          package org.jboss.security.auth.spi;
          
          
          
          import java.security.acl.Group;
          
           import java.util.HashMap;
          
           import java.util.Map;
          
           import java.sql.Connection;
          
           import java.sql.PreparedStatement;
          
           import java.sql.ResultSet;
          
           import java.sql.SQLException;
          
           import javax.naming.InitialContext;
          
           import javax.naming.NamingException;
          
           import javax.sql.DataSource;
          
           import javax.security.auth.Subject;
          
           import javax.security.auth.callback.CallbackHandler;
          
           import javax.security.auth.login.LoginException;
          
           import javax.security.auth.login.FailedLoginException;
          
          
          
           import org.jboss.security.SimpleGroup;
          
           import org.jboss.security.SimplePrincipal;
          
           import org.jboss.security.auth.spi.UsernamePasswordLoginModul
          
          
          
           /**
          
           * A JDBC based login module that supports authentication and
          
           * It is based on two logical tables:
          
           * <ul>
          
           * <li>Principals(PrincipalID text, Password text)
          
           * <li>Roles(PrincipalID text, Role text, RoleGroup text)
          
           * </ul>
          
           * <p>
          
           * LoginModule options:
          
           * <ul>
          
           * <li><em>dsJndiName</em>: The name of the DataSource of the
          
           * <li><em>principalsQuery</em>: The prepared statement query
          
           * <pre>
          
           * "select Password from Principals where PrincipalID=?"
          
           * </pre>
          
           * <li><em>rolesQuery</em>: The prepared statement query, equ
          
           * <pre>
          
           * "select Role, RoleGroup from Roles where PrincipalID=?"
          
           * </pre>
          
           * </ul>
          
           *
          
           * @author <a href="mailto:on@ibis.odessa.ua">Oleg Nitz</a>
          
           * @author Scott.Stark@jboss.org
          
           * @version $Revision: 1.6 $
          
           */
          
           public class DatabaseServerLoginModule extends UsernamePasswo
          
           {
          
           private String dsJndiName;
          
           private String principalsQuery = "select Password from Pri
          
           private String rolesQuery = "select Role, RoleGroup from R
          
          
          
           /**
          
           * Initialize this LoginModule.
          
           */
          
           public void initialize(Subject subject, CallbackHandler ca
          
           {
          
           super.initialize(subject, callbackHandler, sharedState,
          
           dsJndiName = (String) options.get("dsJndiName");
          
           if( dsJndiName == null )
          
           dsJndiName = "java:/DefaultDS";
          
           Object tmp = options.get("principalsQuery");
          
           if( tmp != null )
          
           principalsQuery = tmp.toString();
          
           tmp = options.get("rolesQuery");
          
           if( tmp != null )
          
           rolesQuery = tmp.toString();
          
           log.trace("DatabaseServerLoginModule, dsJndiName="+dsJn
          
           log.trace("principalsQuery="+principalsQuery);
          
           log.trace("rolesQuery="+rolesQuery);
          
           }
          
          
          
           /** Get the expected password for the current username ava
          
           * the getUsername() method. This is called from within th
          
           * method after the CallbackHandler has returned the usern
          
           * candidate password.
          
           * @return the valid password String
          
           */
          
           protected String getUsersPassword() throws LoginException
          
           {
          
           String username = getUsername();
          
           String password = null;
          
           Connection conn = null;
          
           PreparedStatement ps = null;
          
          
          
           try
          
           {
          
           InitialContext ctx = new InitialContext();
          
           DataSource ds = (DataSource) ctx.lookup(dsJndiName);
          
           conn = ds.getConnection();
          
           // Get the password
          
           ps = conn.prepareStatement(principalsQuery);
          
           ps.setString(1, username);
          
           ResultSet rs = ps.executeQuery();
          
           if( rs.next() == false )
          
           throw new FailedLoginException("No matching user
          
          
          
           password = rs.getString(1);
          
           password = convertRawPassword(password);
          
           rs.close();
          
           }
          
           catch(NamingException ex)
          
           {
          
           throw new LoginException(ex.toString(true));
          
           }
          
           catch(SQLException ex)
          
           {
          
           log.error("Query failed", ex);
          
           throw new LoginException(ex.toString());
          
           }
          
           finally
          
           {
          
           if( ps != null )
          
           {
          
           try
          
           {
          
           ps.close();
          
           }
          
           catch(SQLException e)
          
           {}
          
           }
          
           if( conn != null )
          
           {
          
           try
          
           {
          
           conn.close();
          
           }
          
           catch (SQLException ex)
          
           {}
          
           }
          
           }
          
           return password;
          
           }
          
          
          
           /** Overriden by subclasses to return the Groups that cor
          
           to the role sets assigned to the user. Subclasses should
          
           least a Group named "Roles" that contains the roles assi
          
           A second common group is "CallerPrincipal" that provides
          
           identity of the user rather than the security domain ide
          
           @return Group[] containing the sets of roles
          
           */
          
           protected Group[] getRoleSets() throws LoginException
          
           {
          
           String username = getUsername();
          
           Connection conn = null;
          
           HashMap setsMap = new HashMap();
          
           PreparedStatement ps = null;
          
          
          
           try
          
           {
          
           InitialContext ctx = new InitialContext();
          
           DataSource ds = (DataSource) ctx.lookup(dsJndiName)
          
           conn = ds.getConnection();
          
           // Get the users role names
          
           ps = conn.prepareStatement(rolesQuery);
          
           ps.setString(1, username);
          
           ResultSet rs = ps.executeQuery();
          
           if( rs.next() == false )
          
           {
          
           if( getUnauthenticatedIdentity() == null )
          
           throw new FailedLoginException("No matching u
          
           /* We are running with an unauthenticatedIdentit
          
           empty Roles set and return.
          
           */
          
           Group[] roleSets = { new SimpleGroup("Roles") };
          
           return roleSets;
          
           }
          
          
          
           do
          
           {
          
           String name = rs.getString(1);
          
           String groupName = rs.getString(2);
          
           if( groupName == null || groupName.length() ==
          
           groupName = "Roles";
          
           Group group = (Group) setsMap.get(groupName);
          
           if( group == null )
          
           {
          
           group = new SimpleGroup(groupName);
          
           setsMap.put(groupName, group);
          
           }
          
           group.addMember(new SimplePrincipal(name));
          
           } while( rs.next() );
          
           rs.close();
          
           }
          
           catch(NamingException ex)
          
           {
          
           throw new LoginException(ex.toString(true));
          
           }
          
           catch(SQLException ex)
          
           {
          
           super.log.error("SQL failure", ex);
          
           throw new LoginException(ex.toString());
          
           }
          
           finally
          
           {
          
           if( ps != null )
          
           {
          
           try
          
           {
          
           ps.close();
          
           }
          
           catch(SQLException e)
          
           {}
          
           }
          
           if( conn != null )
          
           {
          
           try
          
           {
          
           conn.close();
          
           }
          
           catch (Exception ex)
          
           {}
          
           }
          
           }
          
          
          
           Group[] roleSets = new Group[setsMap.size()];
          
           setsMap.values().toArray(roleSets);
          
           return roleSets;
          
           }
          
          
          
           /** A hook to allow subclasses to convert a password from
          
           into a plain text string or whatever form is used for ma
          
           the user input. It is called from within the getUsersPas
          
           @param rawPassword, the password as obtained from the da
          
           @return the argument rawPassword
          
           */
          
           protected String convertRawPassword(String rawPassword)
          
           {
          
           return rawPassword;
          
           }
          
           }