Jboss 6.2 EAP login module called multiple times at random times for random users
danjee Mar 19, 2014 9:01 AMHello,
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