1 Reply Latest reply on Mar 19, 2014 12:59 PM by danjee

    Jboss 6.2 EAP login module called multiple times at random times for random users

    danjee

      Hello,

       

      I have a problem with my custom login module. This problem appeared in 7.1.1 version but it's still present in 6.2 (7.3.0) version. This is not reproductive all the times.

      Sometimes, without any determined reason the login method in my custom login module gets called for every ejb3 method the operators calls.

      I will try to put pieces of log output, configuration and Java code.

       

      Log output:

       

      12:36:15,922 TRACE [org.jboss.security] (EJB default - 2) PBOX000204: Begin validateCache, domainInfo: org.jboss.security.authentication.JBossCachedAuthenticationManager$DomainInfo@198d2dfc, credential class: class java.lang.String

      12:36:15,922 TRACE [org.jboss.security] (EJB default - 2) PBOX000205: End validateCache, result = false

      12:36:15,922 TRACE [org.jboss.security] (EJB default - 2) PBOX000209: defaultLogin, principal: operator1

      12:36:15,923 TRACE [org.jboss.security] (EJB default - 2) PBOX000221: Begin getAppConfigurationEntry(CaponeJaas), size: 4

      12:36:15,923 TRACE [org.jboss.security] (EJB default - 2) PBOX000224: End getAppConfigurationEntry(CaponeJaas), AuthInfo: AppConfigurationEntry[]:

      [0]

      LoginModule Class: com.asf.capone.server.jaas.CaponeLoginModule

      ControlFlag: LoginModuleControlFlag: required

      Options:

      name=encryption, value=true

      name=debug, value=true

      name=password-stacking, value=useFirstPass

       

       

      12:36:15,923 TRACE [org.jboss.security] (EJB default - 2) PBOX000236: Begin initialize method

      12:36:15,923 WARN  [org.jboss.security] (EJB default - 2) PBOX000234: Invalid or misspelled module option: encryption

      12:36:15,924 WARN  [org.jboss.security] (EJB default - 2) PBOX000234: Invalid or misspelled module option: debug

      12:36:15,924 INFO  [stdout] (EJB default - 2)           [CaponeLoginModule] debug: true

      12:36:15,924 INFO  [stdout] (EJB default - 2)           [CaponeLoginModule] encryption: true

      12:36:15,924 TRACE [org.jboss.security] (EJB default - 2) PBOX000240: Begin login method

      12:36:15,924 INFO  [stdout] (EJB default - 2)           [CaponeLoginModule] use first pass: true

      12:36:15,925 INFO  [stdout] (EJB default - 2)           [CaponeLoginModule] private key file: /appsvr/jboss-caponeagency/bin/private.der

      12:36:15,946 INFO  [stdout] (EJB default - 2)           [CaponeLoginModule] login sql : select id, password, ldap_authentication from users_sv where lower(name) = lower('operator1') and deleted = 0

      12:36:15,948 TRACE [org.jboss.security] (EJB default - 2) PBOX000241: End login method, isValid: true

      12:36:15,948 TRACE [org.jboss.security] (EJB default - 2) PBOX000242: Begin commit method, overall result: true

      12:36:15,948 TRACE [org.jboss.security] (EJB default - 2) PBOX000210: defaultLogin, login context: javax.security.auth.login.LoginContext@6d38b25c, subject: Subject(625339913).principals=org.jboss.security.SimplePrincipal@323324366(operator1)org.jboss.security.SimpleGroup@978992452(Roles(members))org.jboss.security.SimpleGroup@978992452(CallerPrincipal(members:operator1))

      12:36:15,948 TRACE [org.jboss.security] (EJB default - 2) PBOX000207: updateCache, input subject: Subject(625339913).principals=org.jboss.security.SimplePrincipal@323324366(operator1)org.jboss.security.SimpleGroup@978992452(Roles(members))org.jboss.security.SimpleGroup@978992452(CallerPrincipal(members:operator1)), cached subject: Subject(302949373).principals=org.jboss.security.SimplePrincipal@323324366(operator1)org.jboss.security.SimpleGroup@978992452(Roles(members))org.jboss.security.SimpleGroup@978992452(CallerPrincipal(members:operator1))

      12:36:15,949 TRACE [org.jboss.security] (EJB default - 2) PBOX000208: Inserted cache info: org.jboss.security.authentication.JBossCachedAuthenticationManager$DomainInfo@7f30404d

      12:36:15,949 TRACE [org.jboss.security] (EJB default - 2) PBOX000201: End isValid, result = true

      12:36:15,949 TRACE [org.jboss.security.audit] (EJB default - 2) [Success]Source=org.jboss.as.security.service.SimpleSecurityManager;Action=authentication;principal=operator1;

      12:36:15,949 TRACE [org.jboss.security] (EJB default - 2) PBOX000354: Setting security roles ThreadLocal: {}

      12:36:15,954 TRACE [org.jboss.security] (EJB default - 2) PBOX000354: Setting security roles ThreadLocal: null

       

       

      The validate cache seems to return false and then the login module is recalled over and over again. As I said this happens randomly for random users, 90% of the time the login module works as expected.

       

      Pieces of my standalone.xml:

       

      <security-realm name="CaponeRealm">

                      <authentication>

                          <jaas name="CaponeJaas"/>

                      </authentication>

                  </security-realm>

       

              <subsystem xmlns="urn:jboss:domain:remoting:1.1">

                  <connector name="remoting-connector" socket-binding="remoting" security-realm="CaponeRealm"/>

              </subsystem>

       

       

      <security-domains>

                      <security-domain name="CaponeJaas" cache-type="default">

                          <authentication>

                              <login-module code="com.asf.capone.server.jaas.CaponeLoginModule" flag="required" module="deployment.capone.ear.capone-EJB.jar">

                                  <module-option name="password-stacking" value="useFirstPass"/>

                                  <module-option name="debug" value="true"/>

                                  <module-option name="encryption" value="true"/>

                              </login-module>

                          </authentication>

                      </security-domain>

      ...

      </security-domains>

       

      debug and encryption are two custom options of my module.

       

      In the CaponeLoginModule I have these methods:

       

      @Override

        public void initialize(final Subject subject, final CallbackHandler callbackHandler, final Map sharedState,

        final Map options) {

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

        this.options = options;

        encryption = "true".equalsIgnoreCase((String) options.get("encryption"));

        printConfiguration(this);

        }

       

       

       

      This is taken from Darran Lofthouse's RemoteLoginModule

      @Override

        protected Group[] getRoleSets() {

        Group roles = new SimpleGroup("Roles");

        Group callerPrincipal = new SimpleGroup("CallerPrincipal");

        Group[] groups = { roles, callerPrincipal };

        callerPrincipal.addMember(getIdentity());

        return groups;

        }

       

      This is my custom business logic (verify password upon a database value or ldap)

       

      @Override

        protected String getUsersPassword() throws LoginException {

        String[] credentials = getUsernameAndPassword();

        String username = credentials[0];

        String password = credentials[1];

       

       

        String cypherPassword = password;

        boolean successLogin = false;

        if (encryption() && password.length() > 30) {

        try {

        String privateKeyFilePath = "private.der";

        File privateKeyFile = new File(privateKeyFilePath);

        if (privateKeyFile.exists()) {

        logger.trace("private key file: " + privateKeyFile.getAbsolutePath());

        } else {

        throw new LoginException("Private key file not found!");

        }

        PrivateKey privateKey = Decrypter.loadPrivateKey(privateKeyFilePath, Decrypter.ALGORITHM_RSA);

        cypherPassword = Decrypter.decrypt(privateKey, password);

        } catch (Exception e) {

        throw new LoginException(e.getMessage());

        }

        }

       

       

        Connection connection = null;

        Statement statement = null;

        ResultSet rs = null;

       

       

        try {

        connection = DataBaseUtils.getJndiConnection();

        statement = connection.createStatement();

        String ldapUrl = PropsUtils.getAdUrl();

        String loginSql = "select id, password, ldap_authentication from users_sv " + "where lower(name) = lower('"

        + username + "') and deleted = 0";

        logger.debug("login sql : " + loginSql);

        rs = statement.executeQuery(loginSql);

       

       

        if (rs.next()) {

        Long id = rs.getLong(1);

        String dbPassword = rs.getString(2);

        Boolean ldapAuthentication = rs.getInt(3) == 1;

        try {

        if (ldapAuthentication) {

        successLogin = loginThroughLdap(username, cypherPassword, ldapUrl);

        } else {

        successLogin = loginThroughDb(username, DigestUtils.md5Hex(cypherPassword), dbPassword);

        }

        } catch (Exception e) {

        doAudit(AuditUtils.LOGIN_OPERATION, id, username, false, !ldapAuthentication, e.getMessage());

        e.printStackTrace();

        }

        } else {

        throw new FailedLoginException("Unknown Capone User");

        }

        } catch (Exception e) {

        logger.debug("For some reason authentication failed! {}", e);

        } finally {

        try {

        if (connection != null) {

        connection.close();

        }

        } catch (Exception e) {

        e.printStackTrace();

        }

        try {

        if (statement != null) {

        statement.close();

        }

        } catch (Exception e) {

        e.printStackTrace();

        }

        try {

        if (rs != null) {

        rs.close();

        }

        } catch (Exception e) {

        e.printStackTrace();

        }

        }

        // Workaround to make it work with Jboss usernamepassword login module.

        // Will return the password that user entered because authentication was

        // already established

        if (successLogin) {

        return password;

        } else {

        return "NO_WAY_A_VALID_PASSWORD=" + UUID.randomUUID().toString();

        }

        }

       

       

      Some posts I've read read about overriding SimplePrincipals equals method. I believe this is not my case considering I do not make a new instance of the SimplePrincipal when authenticating.

      Can someone point me the exact fix for this ?

       

      Thank you ,

       

      Daniel Jipa