8 Replies Latest reply on Jul 6, 2011 2:46 PM by Wolfgang Knauf

    Facing JAAS issue while moving from Jboss 4 to 5.0.1

    Ajay Arora Newbie

      Hi,

       

      The next issue now I am facing is an authentcation exception when trying to access an EJB which is protected by roles and oauthorized via custom jaas login depending upon the user roles in the Database.

       

      Error I am getting :

      2011-06-21 12:58:52,193 ERROR [org.jboss.ejb.plugins.SecurityInterceptor] (main) Error in Security Interceptor
      java.lang.SecurityException: Authentication exception, principal=SessionTimer1
      at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityContext(SecurityInterceptor.java:321)
      at org.jboss.ejb.plugins.SecurityInterceptor.process(SecurityInterceptor.java:243)
      at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:205)
      at org.jboss.ejb.plugins.security.PreSecurityInterceptor.process(PreSecurityInterceptor.java:136)
      at org.jboss.ejb.plugins.security.PreSecurityInterceptor.invokeHome(PreSecurityInterceptor.java:88)
      at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:132)
      at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:107)
      at org.jboss.ejb.EntityContainer.internalInvokeHome(EntityContainer.java:527)
      at org.jboss.ejb.Container.invoke(Container.java:1046)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:585)
      at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157)
      at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96)
      at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
      at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
      at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668)
      at org.jboss.invocation.local.LocalInvoker$MBeanServerAction.invoke(LocalInvoker.java:169)
      at org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:118)
      at org.jboss.invocation.InvokerInterceptor.invokeLocal(InvokerInterceptor.java:209)
      at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:195)
      at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:61)
      at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:68)
      at org.jboss.proxy.ejb.HomeInterceptor.invoke(HomeInterceptor.java:184)
      at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:101)
      at $Proxy529.findByPrimaryKey(Unknown Source)
      at sync.server.util.SyncConfig.init(SyncConfig.java:497)

       

       

      Here is the code:

      SyncUtils.jaasLogin(Constants.INTERNAL_APPLICATION_USER, SyncUtils.getPassword(Constants.INTERNAL_APPLICATION_USER));
      ctx = new InitialContext()

      SystemProfileHome home = (SystemProfileHome)ctx.lookup(SystemProfileHome.class.getName());
      SystemProfileEB eb = home.findByPrimaryKey(new SystemProfilePK(1));

       

      We are useing the jboss jaas client-module to set the uname and its password and then call find by primary key on entity bean. Unfortunately in Jboss 5 the custom jaas login module is not getting the uname and pwd from the callbackhandler as they are returned as null.

       

      Again this works fine in Jboss 4.0.3.

       

      Looking forward to hear your thoughts and thanks for any help in advance.

        • 1. Re: Facing JAAS issue while moving from Jboss 4 to 5.0.1
          Wolfgang Knauf Master

          Hi,

           

          could you provide more detail about your implementation (mainly the content of "SyncUtils.jaasLogin" and your security config)?

           

          You might activate logging of the security layer. See here (http://wiki.jboss.org/wiki/Wiki.jsp?page=SecurityFAQ), question 4.

           

          Best regards

           

          Wolfgang

          • 2. Re: Facing JAAS issue while moving from Jboss 4 to 5.0.1
            Ajay Arora Newbie

            SyncUtils.jassLogin :

              public static boolean jaasLogin(String username, String password)
              {
                boolean retVal = false;

                try
                {
                  LoginContext loginContext = new LoginContext("client-login", new LoginCallbackHandler(username, password));
                  loginContext.login();

                  retVal = true;
                }
                catch (Exception ex)
                {
                  log("UT:SUT.jaasLogin",Logger.LOG_TRACE,0,0,"Unable to login to JAAS",ex,null);
                }

                return retVal;
              }

            --------

             

            After I enbaled the tracing:

            2011-06-21 16:50:54,044 TRACE [org.jboss.security.auth.login.XMLLoginConfigImpl] (main) Begin getAppConfigurationEntry(client-login), size=11
            2011-06-21 16:50:54,044 TRACE [org.jboss.security.auth.login.XMLLoginConfigImpl] (main) End getAppConfigurationEntry(client-login), authInfo=AppConfigurationEntry[]:
            [0]
            LoginModule Class: org.jboss.security.ClientLoginModule
            ControlFlag: LoginModuleControlFlag: required
            Options:
            name=multi-threaded, value=true

            2011-06-21 16:50:54,047 TRACE [org.jboss.security.ClientLoginModule] (main) Security domain: client-login
            2011-06-21 16:50:54,047 TRACE [org.jboss.security.ClientLoginModule] (main) Enabling multi-threaded mode
            2011-06-21 16:50:54,049 TRACE [org.jboss.security.ClientLoginModule] (main) Enabling restore-login-identity mode
            2011-06-21 16:50:54,050 TRACE [org.jboss.security.ClientLoginModule] (main) Begin login
            2011-06-21 16:50:54,050 TRACE [org.jboss.security.ClientLoginModule] (main) Obtained login: SessionTimer1, credential.class: [C
            2011-06-21 16:50:54,050 TRACE [org.jboss.security.ClientLoginModule] (main) End login
            2011-06-21 16:50:54,050 TRACE [org.jboss.security.ClientLoginModule] (main) commit, subject=Subject:

            2011-06-21 16:50:54,097 TRACE [org.jboss.security.plugins.auth.JaasSecurityManagerBase.sync-login] (main) Begin isValid, principal:null, cache info: null
            2011-06-21 16:50:54,097 TRACE [org.jboss.security.plugins.auth.JaasSecurityManagerBase.sync-login] (main) defaultLogin, principal=null
            2011-06-21 16:50:54,097 TRACE [org.jboss.security.auth.login.XMLLoginConfigImpl] (main) Begin getAppConfigurationEntry(sync-login), size=11
            2011-06-21 16:50:54,097 TRACE [org.jboss.security.auth.login.XMLLoginConfigImpl] (main) End getAppConfigurationEntry(sync-login), authInfo=AppConfigurationEntry[]:
            [0]
            LoginModule Class: sync.server.system.SyncServerLoginModule
            ControlFlag: LoginModuleControlFlag: required
            Options:
            name=dsJndiName, value=jdbc/DefaultDS

            2011-06-21 16:50:54,103 INFO  [Sync] (Thread-27)          0|         0| main            | ncServerLoginModule.initialize|  init sync-login
            2011-06-21 16:50:54,103 INFO  [Sync] (Thread-27)          0|         0| main            | ncServerLoginModule.initialize|  login sync-login
            2011-06-21 16:50:54,104 TRACE [org.jboss.security.plugins.auth.JaasSecurityManagerBase.sync-login] (main) Login failure
            javax.security.auth.login.FailedLoginException: Username and Password Required
            at sync.server.system.SyncServerLoginModule.login(SyncServerLoginModule.java:219)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            at java.lang.reflect.Method.invoke(Method.java:585)
            at javax.security.auth.login.LoginContext.invoke(LoginContext.java:769)
            at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
            at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
            at java.security.AccessController.doPrivileged(Native Method)
            at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
            at javax.security.auth.login.LoginContext.login(LoginContext.java:579)
            at org.jboss.security.plugins.auth.JaasSecurityManagerBase.defaultLogin(JaasSecurityManagerBase.java:552)
            at org.jboss.security.plugins.auth.JaasSecurityManagerBase.authenticate(JaasSecurityManagerBase.java:486)
            at org.jboss.security.plugins.auth.JaasSecurityManagerBase.isValid(JaasSecurityManagerBase.java:365)
            at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:160)
            at org.jboss.security.javaee.EJBAuthenticationHelper.isValid(EJBAuthenticationHelper.java:87)
            at org.jboss.ejb.plugins.SecurityActions$13.run(SecurityActions.java:543)
            at org.jboss.ejb.plugins.SecurityActions$13.run(SecurityActions.java:541)
            at java.security.AccessController.doPrivileged(Native Method)
            at org.jboss.ejb.plugins.SecurityActions.isValid(SecurityActions.java:539)
            at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityContext(SecurityInterceptor.java:314)
            at org.jboss.ejb.plugins.SecurityInterceptor.process(SecurityInterceptor.java:243)
            at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:205)
            at org.jboss.ejb.plugins.security.PreSecurityInterceptor.process(PreSecurityInterceptor.java:136)
            at org.jboss.ejb.plugins.security.PreSecurityInterceptor.invokeHome(PreSecurityInterceptor.java:88)
            at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:132)
            at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:107)
            at org.jboss.ejb.EntityContainer.internalInvokeHome(EntityContainer.java:527)
            at org.jboss.ejb.Container.invoke(Container.java:1046)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            at java.lang.reflect.Method.invoke(Method.java:585)
            at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157)
            at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96)
            at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
            at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
            at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668)
            at org.jboss.invocation.local.LocalInvoker$MBeanServerAction.invoke(LocalInvoker.java:169)
            at org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:118)
            at org.jboss.invocation.InvokerInterceptor.invokeLocal(InvokerInterceptor.java:209)
            at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:195)
            at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:61)
            at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:68)
            at org.jboss.proxy.ejb.HomeInterceptor.invoke(HomeInterceptor.java:184)
            at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:101)
            at $Proxy529.findByPrimaryKey(Unknown Source)
            at sync.server.util.SyncConfig.init(SyncConfig.java:497)
            at sync.server.util.SyncConfig.getDatabaseAddress(SyncConfig.java:641)
            at sync.server.util.SyncUtils.getDbIP(SyncUtils.java:2032)
            at sync.server.license.Restrictions.init(Restrictions.java:48)
            at sync.server.util.SyncStartup.checkLicense(SyncStartup.java:198)
            at sync.server.util.SyncStartup.start(SyncStartup.java:115)

             

            Basically I wants the username, password passed to jboss 'client-login' module should passed to my  (in non-interactive way) custom login module 'sync-login' in which I get the username and password from the callbackhandler and get the assigned roles from the database but the username and password used in 'client-login' are coming null in 'sync-login' which is the security domain declared in jboss.xml for the ejb as    <security-domain>java:/jaas/sync-login</security-domain>

             

            Again this works in Jboss 4.

             

            One difference I noticed is the callback handler class is different:

            in Jboss 5

            - 2011-06-21 16:49:35,892 DEBUG [org.jboss.security.plugins.JaasSecurityManagerService] (main) CallbackHandlerClass=class org.jboss.security.auth.callback.JBossCallbackHandler

            In Jboss 4 -

            2011-06-21 12:13:33,990 DEBUG [JaasSecurityManagerService] CallbackHandlerClass=class org.jboss.security.auth.callback.SecurityAssociationHandler

             

            thanks

             

             

             

            • 3. Re: Facing JAAS issue while moving from Jboss 4 to 5.0.1
              Wolfgang Knauf Master

              Could you post also the code of "sync.server.system.SyncServerLoginModule"?

               

              Some time ago, I had a login module (but also for AS 4.x, I never needed to update it for AS 5). Maybe this "inspires" you ;-):

               

               

              {code}

              public class MyLoginModule extends UsernamePasswordLoginModule

              {

                ...

               

                public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)

                {

                  super.initialize(subject, callbackHandler, sharedState, options);

                 

                  ...get e.g. datasource

               

                }

               

                protected Group[] getRoleSets() throws LoginException

                {

                  try

                  {

                    Group[] groups = { new SimpleGroup("Roles") };

               

                    String sUserName = super.getUsername();

                    //We have two possible roles: "customer" and "admin".

                    if (sUserName is customer...)

                    {

                      SimplePrincipal role = new SimplePrincipal("customer");

                      groups[0].addMember(role);

                      return groups;

                    }

                    else if (sUserName is admin...)

                    {

                      SimplePrincipal role = new SimplePrincipal("admin");

                      groups[0].addMember(role);

                      return groups;

                    }

                    else

                    {

                      ...error

                    }

                  }

                  catch (SQLException e)

                  {

                    log.error("Error in getUsersPassword for User " + super.getUsername(), e);

                    throw new LoginException(e.getMessage());

                  }

                }

               

                protected String getUsersPassword() throws LoginException

                {

                  try

                  {

                    //Get password for current username

                    String strUserName = super.getUsername());

                    ...find password for User and return it...

                  }

                  catch (SQLException e)

                  {

                    log.error("Error in getUsersPassword for User " + super.getUsername(), e);

                    throw new LoginException(e.getMessage());

                  }

                }

              }

              {code}

               

              Best regards

               

              Wolfgang

              • 4. Re: Facing JAAS issue while moving from Jboss 4 to 5.0.1
                Ajay Arora Newbie

                Here is the full code:

                 

                package sync.server.system;

                import java.security.acl.Group;
                import java.security.Principal;
                import java.sql.Connection;
                import java.sql.PreparedStatement;
                import java.sql.ResultSet;
                import java.sql.SQLException;
                import java.util.Enumeration;
                import java.util.HashMap;
                import java.util.HashSet;
                import java.util.Iterator;
                import java.util.Map;
                import java.util.Set;
                import javax.naming.InitialContext;
                import javax.naming.NamingException;
                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.LoginException;
                import javax.security.auth.spi.LoginModule;
                import javax.security.auth.login.FailedLoginException;
                import javax.sql.DataSource;
                import sync.server.util.SyncUtils;
                import sync.util.Logger;
                import sync.util.Constants;

                public class SyncServerLoginModule implements LoginModule
                {
                  private static final long DEFAULT_CACHE_DURATION = 0; // No built-in caching
                  protected boolean loginOk;
                  protected Subject subject;
                  private char[] credential;
                  protected CallbackHandler callbackHandler;
                  protected Map sharedState;
                  protected Map options;
                  private SimpleGroup roles = new SimpleGroup("Roles");
                  private Principal identity;
                  private String dsJndiName;
                  private long validCacheTime = DEFAULT_CACHE_DURATION;
                  private String roleQuery = "select r.user_role_desc as Role from SCC_USER_ROLE r, SCC_USER u where r.user_role_id=u.user_role_id and u.user_name=? and u.password=?";
                  private static HashMap cachedMap = new HashMap();
                  private static Object lock = new Object();

                  /**
                  * Initialize this LoginModule.
                  */
                  public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
                  {
                      SyncUtils.log("SyncServerLoginModule.initialize", Logger.LOG_MIN_INFO, 0, 0," init sync-login", null, null);

                    this.subject = subject;
                    this.callbackHandler = callbackHandler;
                    this.sharedState = sharedState;
                    this.options = options;

                    dsJndiName = (String) options.get("dsJndiName");
                    if( dsJndiName == null )
                      dsJndiName = Constants.JDBC_DATA_SOURCE;
                    String tmp = (String)options.get("roleQuery");
                    if( tmp != null )
                      roleQuery = tmp.toString();
                    tmp = (String)options.get("cacheDurationMS");
                    if( tmp != null )
                    {
                      try
                      {
                        validCacheTime = Long.parseLong(tmp);
                      }
                      catch (NumberFormatException nfe)
                      {
                        SyncUtils.log("SSLM.initialize", Logger.LOG_ERROR, 0, 0,
                          "Invalid cache duration (ms): " + tmp, null, null);
                      }
                    }
                  }

                  protected String getRole(String username, String password) throws LoginException
                  {
                        SyncUtils.log("SyncServerLoginModule.initialize", Logger.LOG_MIN_INFO, 0, 0," getrole sync-login", null, null);
                    Connection conn = null;
                    String role = null;
                    PreparedStatement ps = null;
                    InitialContext ctx = null;
                    ResultSet rs = null;
                    try
                    {
                      ctx = new InitialContext();
                      DataSource ds = (DataSource) ctx.lookup(dsJndiName);
                      conn = ds.getConnection();
                      // Get the user role names
                      ps = conn.prepareStatement(roleQuery);
                      try
                      {
                        ps.setString(1, username);
                        ps.setString(2, password);
                      }
                      catch(ArrayIndexOutOfBoundsException ignore)
                      {
                        // The query may not have any parameters so just try it
                      }

                      SyncUtils.log("SyncServerLoginModule.getRole", Logger.LOG_DEBUG_INFO, 0, 0,
                        "Retrieving user role from database for user " + username, null, null);
                       
                      rs = ps.executeQuery();
                      if( rs.next() == false )
                      {
                        throw new FailedLoginException("No matching username and password found");
                      }
                      else
                      {
                        role = rs.getString(1);
                      }
                    }
                    catch(NamingException ex)
                    {
                      throw new LoginException(ex.toString(true));
                    }
                    catch(SQLException ex)
                    {
                      throw new LoginException(ex.toString());
                    }
                    finally
                    { 
                      SyncUtils.closeConnection(rs, ps, conn);
                      SyncUtils.closeContext(ctx);
                      ctx = null;
                    }

                    return role;
                  }

                  /** Called by login() to acquire the username and password strings for
                  authentication. This method does no validation of either.
                  @return String[], [0] = username, [1] = password
                  @exception LoginException thrown if CallbackHandler is not set or fails.
                  */
                  protected String[] getUsernameAndPassword() throws LoginException
                  {
                    SyncUtils.log("SyncServerLoginModule.initialize", Logger.LOG_MIN_INFO, 0, 0," getUsernameAndPassword1 sync-login", null, null);

                    String[] info = {null, null};
                    // prompt for a username and password
                    if( callbackHandler == null )
                    {
                      throw new LoginException("Error: no CallbackHandler available " +
                      "to collect authentication information");
                    }

                    SyncUtils.log("SyncServerLoginModule.initialize", Logger.LOG_MIN_INFO, 0, 0," getUsernameAndPassword2 sync-login", null, null);

                    NameCallback nc = new NameCallback("User name: ", "guest");
                    PasswordCallback pc = new PasswordCallback("Password: ", false);
                    Callback[] callbacks = {nc, pc};
                    String username = null;
                    String password = null;

                SyncUtils.log("SyncServerLoginModule.initialize", Logger.LOG_MIN_INFO, 0, 0," getUsernameAndPassword3 sync-login", null, null);

                    try
                    {
                      callbackHandler.handle(callbacks);
                      username = nc.getName();
                      char[] tmpPassword = pc.getPassword();
                      if( tmpPassword != null )
                      {
                        credential = new char[tmpPassword.length];
                        System.arraycopy(tmpPassword, 0, credential, 0, tmpPassword.length);
                        pc.clearPassword();
                        password = new String(credential);
                      }
                    }
                    catch(java.io.IOException ioe)
                    {
                  throw new LoginException(ioe.toString());
                    }
                    catch(UnsupportedCallbackException uce)
                    {
                  throw new LoginException("CallbackHandler does not support: " + uce.getCallback());
                    }
                    info[0] = username;
                    info[1] = password;

                    return info;
                  }

                  /** Perform the authentication of the username and password.
                  */
                  public boolean login() throws LoginException
                  {
                SyncUtils.log("SyncServerLoginModule.initialize", Logger.LOG_MIN_INFO, 0, 0," login sync-login", null, null);

                    loginOk = false;
                    String info[] = getUsernameAndPassword();
                    String username = info[0];
                    String password = info[1];

                if( username == null || password == null )
                    {
                  throw new FailedLoginException("Username and Password Required");
                    }
                 
                    String role = null;

                    if (validCacheTime == 0)
                    {
                      role = getRole(username, password);
                    }
                    else
                    {
                      synchronized (lock)
                      {
                        CachedData cachedData = (CachedData)cachedMap.get(username.toLowerCase());
                        if ((cachedData != null) && !cachedData.isExpired() && cachedData.isPasswordValid(password))
                        {
                          role = cachedData.getRole();
                        }
                        else
                        {
                          role = getRole(username, password);
                          cachedMap.put(username.toLowerCase(), new CachedData(username, password, role));
                        }
                      }
                    }

                    identity = new SimplePrincipal(username);
                    roles.addMember(new SimplePrincipal(role));

                    loginOk = true;
                    return true;
                  }

                  /** Method to commit the authentication process (phase 2). If the login
                  method completed successfully as indicated by loginOk == true, this
                  method adds the getIdentity() value to the subject getPrincipals() Set.
                  It also adds the members of each Group returned by getRoleSets()
                  to the subject getPrincipals() Set.

                  @see javax.security.auth.Subject;
                  @see java.security.acl.Group;
                  @return true always.
                  */
                  public boolean commit() throws LoginException
                  {
                if( loginOk == false )
                      return false;

                    Set principals = subject.getPrincipals();
                    principals.add(identity);
                    Group subjectGroup = findGroup("Roles", principals);
                    if (subjectGroup == null)
                    {
                      principals.add(roles);
                    }
                    return true;
                  }

                  /** Method to abort the authentication process (phase 2).
                  @return true alaways
                  */
                  public boolean abort() throws LoginException
                  {
                return true;
                  }

                  /** Remove the user identity and roles added to the Subject during commit.
                  @return true always.
                  */
                  public boolean logout() throws LoginException
                  {
                Set principals = subject.getPrincipals();
                    principals.remove(identity);

                    return true;
                  }

                  /**
                  * Find a Group with the given name. Subclasses should use this
                  * method to locate the 'Roles' group or create additional types of groups.
                  *
                  * @return A named Group from the principals set.
                  */
                  protected Group findGroup(String name, Set principals)
                  {
                  Group roles = null;
                  Iterator iter = principals.iterator();
                  while( iter.hasNext() )
                  {
                    Object next = iter.next();
                    if( (next instanceof Group) == false )
                      continue;
                    Group grp = (Group) next;
                    if( grp.getName().equals(name) )
                    {
                      roles = grp;
                      break;
                    }
                  }
                  return roles;
                  }

                  public class SimplePrincipal
                  implements Principal
                  {
                  private String username = null;

                  public SimplePrincipal(String name)
                  {
                    username = name;
                  }

                  public boolean equals(Object another)
                  {
                    if ((another != null) && (another instanceof String))
                    {
                      String s = (String)another;
                      return s.equalsIgnoreCase(username);
                    }
                    return false;
                  }

                  public String getName()
                  {
                    return username;
                  }

                  public int hashCode()
                  {
                    return username.hashCode();
                  }

                  public String toString()
                  {
                    return getName();
                  }
                  }

                  public class SimpleGroup extends SimplePrincipal
                  implements Group
                  {
                  private HashSet members = new HashSet();

                  public SimpleGroup(String name)
                  {
                    super(name);
                  }

                  public boolean addMember(Principal user)
                  {
                    return members.add(user);
                  }

                  public boolean isMember(Principal user)
                  {
                    return members.contains(user);
                  }

                  public Enumeration members()
                  {
                    return new SimpleGroupEnumeration(members.iterator());
                  }

                  public boolean removeMember(Principal user)
                  {
                    return members.remove(user);
                  }
                  }

                  public class SimpleGroupEnumeration
                  implements Enumeration
                  {
                  private Iterator iter = null;

                  public SimpleGroupEnumeration(Iterator iter)
                  {
                    this.iter = iter;
                  }

                  public boolean hasMoreElements()
                  {
                    return iter.hasNext();
                  }

                  public Object nextElement()
                  {
                    return iter.next();
                  }
                  }

                  protected class CachedData
                  {
                    private long cacheTime = 0;
                    private String username = null;
                    private String password = null;
                    private String role = null;

                    public CachedData(String username, String password, String role)
                    {
                      this.username = username;
                      this.password = password;
                      this.role = role;
                      this.cacheTime = System.currentTimeMillis();
                    }

                    public boolean isExpired()
                    {
                      return ((System.currentTimeMillis() - cacheTime) > validCacheTime);
                    }

                    public String getUsername()
                    {
                      return username;
                    }

                    public boolean isPasswordValid(String newPw)
                    {
                      if (password != null)
                      {
                        return password.equalsIgnoreCase(newPw);
                      }
                      else if (newPw == null)
                      {
                        return true;
                      }
                      return false;
                    }

                    public String getRole()
                    {
                      return role;
                    }
                  }
                }

                • 5. Re: Facing JAAS issue while moving from Jboss 4 to 5.0.1
                  Wolfgang Knauf Master

                  Hi,

                   

                  it seems you adopted the code of the "UserNamePasswordLoginModule" (e.g. this http://www.docjar.com/html/api/org/jboss/security/auth/spi/UsernamePasswordLoginModule.java.html )

                  Maybe it helps to subclass "AbstractServerLoginModule" instead of just implementing the interface? Then e.g. "initialize" should call the base class method first.

                   

                  And I think your code might become much shorter if you follow my approach and subclass "UsernamePasswordLoginModule". Now username and password will be provided by the framework and your code will become much shorter.

                   

                  Best regards

                   

                  Wolfgang

                  • 7. Re: Facing JAAS issue while moving from Jboss 4 to 5.0.1
                    Ajay Arora Newbie

                    Hi,

                     

                    I tried it and it didn't work. I am still debugging it and even tried latest Jboss 6 GA with jdk 1.6.0.26 but no succes yet though I compared and found some thing on Jboss 4.0.3 where its working fine.

                     

                    In JBoss 4 on tracing I found this when ClientLoginModule is passed and commit is called:

                     

                    TRACE [ClientLoginModule] End login
                    TRACE [ClientLoginModule] commit, subject=Subject:

                     

                    ---

                    TRACE [SecurityAssociation] pushSubjectContext, subject=Subject:, sc=org.jboss.security.SecurityAssociation$SubjectContext@10d75a3{principal=SessionTimer1,subject=10892380}

                    TRACE [SecurityAssociation] getPrincipal, principal=SessionTimer1
                    ----

                     

                    But the above two lines doesn't appear on Jboss 5 or 6 so I think that is why the my custom jass login does not see user name and password which should have been propagated after clientloginmodule is through.

                     

                    Can you review this and you may know if I am missing any important setting here?

                     

                    Thanks. 

                    • 8. Re: Facing JAAS issue while moving from Jboss 4 to 5.0.1
                      Wolfgang Knauf Master

                      Sorry, I don't have much more ideas I have to admit.

                       

                      I assume that you modified your login module. Could you post the current code?

                       

                      As you seem to keep username and password in a database table: any chance to just kick your login module and use the JBoss built-in module "org.jboss.security.auth.spi.DatabaseServerLoginModule"? You might take a look e.g. at this document for an overview: http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/4.2/html/Server_Configuration_Guide/Using_JBoss_Login_Modules-DatabaseServerLoginModule.html (a bit older, but the content is still valid, though "login-config.xml" can be considered deprecated.

                       

                      If possible, you might modify your database structure for testing it with this login module.

                       

                      Best regards

                       

                      Wolfgang