WildFly 9.0.2 - Custom Login and disable ApplicationRealm Authentication
jworld3333 May 12, 2016 5:58 PMHi there,
I'm working on a custom login (by extending org.jboss.security.auth.spi.UsernamePasswordLoginModule) for my EJBs in wildfly 9.0.2. I am able to get my Custom Login to work (by printing out the information in login()) but it appears that another authentication from ApplicationRealm was also invoked. I'm trying to disable authentication from ApplicationRealm, but have no luck.
Here are what I want to achieve:
1) to use my custom login ONLY to authenticate EJB clients
2) to obtain plain text password within my custom login module for validation in my DAO class. For some reasons, getUsernameAndPassword()[1] always returns org.jboss.as.security.remoting.RemotingConnectionCredential@xxxxxx for password. Not sure if it has to do with ApplicationRealm authentication.
Please let me know if you need more information. Any help is greatly appreciated!!!
Here are my configurations:
standalone-full.xml
<subsystem xmlns="urn:jboss:domain:security:1.2">
<security-domains>
<security-domain name="MyCustomDomain" cache-type="default">
<authentication>
<login-module code="com.my.security.MyLoginModuleImpl" flag="required" module="myModule">
<module-option name="datasourceName" value="java:/MyOracleDS"/>
<module-option name="datasourceSchema" value="mytest"/>
</login-module>
</authentication>
<authorization>
<policy-module code="PermitAll" flag="required"/>
</authorization>
</security-domain>
<security-domain name="other" cache-type="default">
<authentication>
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
<login-module code="RealmDirect" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
</authentication>
</security-domain>
...
</security-domains>
...
</subsystem>
<subsystem xmlns="urn:jboss:domain:ejb3:3.0">
...
<remote connector-ref="http-remoting-connector" thread-pool-name="default"/>
...
<default-missing-method-permissions-deny-access value="true"/>
...
</subsystem>
...
<subsystem xmlns="urn:jboss:domain:remoting:3.0">
<endpoint worker="default"/>
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
</subsystem>
...
<security-realms>
<security-realm name="ManagementRealm">
<authentication>
<local default-user="$local" skip-group-loading="true"/>
<properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization map-groups-to-roles="false">
<properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
<security-realm name="ApplicationRealm">
<authentication>
<local default-user="$local" allowed-users="*" skip-group-loading="true"/>
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
</security-realms>
My Custom Login Java File:
package com.my.security;
import java.security.acl.Group;
import java.sql.Connection;
import java.util.*;
import javax.security.auth.Subject;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import org.jboss.security.SimpleGroup;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.auth.spi.UsernamePasswordLoginModule;
public class MyLoginModuleImpl extends UsernamePasswordLoginModule {
private String dataSourceName;
private String dataBaseSchema;
private MyAuthenticatorDatabase myAuthenticatorDatabase;
private boolean loginSucceeded = false;
public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
{
super.initialize(subject, callbackHandler, sharedState, options);
dataSourceName = (String)options.get("datasourceName");
System.out.println("dataSourceName:"+dataSourceName);
dataBaseSchema = (String)options.get("datasourceSchema");
System.out.println("dataBaseSchema:"+dataBaseSchema);
myAuthenticatorDatabase = new MyAuthenticatorDatabase(dataSourceName);
}
@Override
protected boolean validatePassword(String inputPassword, String expectedPassword) {
System.out.println("called validatePassword()");
return true;
}
@Override
protected String getUsersPassword() throws LoginException {
System.out.println("called getUsersPassword()");
String[] usernamePassword = super.getUsernameAndPassword();
String password = usernamePassword[1];
System.out.format("MyLoginModuleImpl: getUsersPassword(): password '%s'\n", password);
return password;
}
@Override
public boolean login() throws LoginException {
UserDAO userDAO = null;
Connection conn = null;
try {
conn = myAuthenticatorDatabase.getConnection();
userDAO = new UserDAO(conn);
userDAO.setDataBaseSchema(dataBaseSchema);
final String[] usernameAndPassword = getUsernameAndPassword();
String inputPassword = usernameAndPassword[1];
//String encryptedInputPassword = (inputPassword == null)? null : inputPassword;
System.out.format("input password: '%s' \n", inputPassword);
String username = usernameAndPassword[0];
System.out.println("username:"+ username);
if (username != null && username.length() > 0) {
if (!userDAO.userExists(username)) {
System.out.println("User DOES NOT exist!");
throw new FailedLoginException("Authentication Failed: Could not find user:" + username);
}
if (!userDAO.validPassword(username, inputPassword)) {
System.out.println("User password is invalid!");
throw new FailedLoginException("Authentication Failed: Password incorrect for user" + username);
}
} else {
System.out.println("Username is NULL. username="+ username);
// No Username, so anonymous access is being attempted
}
loginSucceeded = true;
} catch (Exception e) {
System.out.println("ERROR FOUND:"+e);
//logger.info("Error Found " + e);
} finally {
try{ conn.close(); } catch(Exception e){}
}
super.loginOk = loginSucceeded;
return loginSucceeded;
}
/**
* (required) The groups of the user, there must be at least one group called
* "Roles" (though it likely can be empty) containing the roles the user has.
*/
@Override
protected Group[] getRoleSets() throws LoginException {
SimpleGroup group = new SimpleGroup("Roles");
try {
System.out.println("Search here group for user: "+super.getUsername());
group.addMember(new SimplePrincipal("Manager"));
} catch (Exception e) {
throw new LoginException("Failed to create group member for " + group);
}
return new Group[] { group };
}
@Override
public boolean commit() throws LoginException {
return loginSucceeded;
}
@Override
public boolean abort() throws LoginException {
return loginSucceeded;
}
@Override
public boolean logout() throws LoginException {
return true;
}
}
module.xml
<module xmlns="urn:jboss:module:1.1" name="myModule">
<resources>
<resource-root path="myAuth.jar"/>
</resources>
<dependencies>
<module name="org.picketbox"/>
<module name="javax.api"/>
<module name="org.jboss.as.controller"/>
</dependencies>
</module>