I have created custom login module in one jar of my ear file, Here is the login module code:
package com.app.module.products.jboss.security.login;
import java.security.Principal;
import java.security.acl.Group;
import javax.security.auth.callback.Callback;
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 org.jboss.security.SimpleGroup;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.auth.spi.AbstractServerLoginModule;
import com.app.module.security.auth.DBAuthenticateModule;
import com.app.module.util.DebugUtil;
public class CustomLoginModule extends AbstractServerLoginModule
{
private Principal identity;
private Group[] roleSets;
private DBAuthenticateModule authenticator;
public CustomLoginModule()
{
authenticator = new DBAuthenticateModule();
}
private char[] credential;
public boolean login() throws LoginException
{
super.loginOk = false;
String[] info = getUsernameAndPassword();
String username = info[0];
String password = info[1];
identity = createIdentity( username);
if (authenticator.authenticate( username, password))
{
super.loginOk = true;
return true;
}
else
{
return false;
}
}
protected Group[] getRoleSets() throws LoginException
{
if (roleSets == null)
{
SimpleGroup rolesGroup = new SimpleGroup( "Roles");
rolesGroup.addMember( new SimplePrincipal( "AppRole"));
roleSets = new Group[] { rolesGroup };
}
return roleSets;
}
protected Principal createIdentity( String username) throws LoginException
{
SimplePrincipal principal = new SimplePrincipal( username);
return principal;
}
protected Principal getIdentity()
{
return identity;
}
/**
* 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
{
String[] info = { null, null };
// prompt for a username and password
if (callbackHandler == null)
{
throw new LoginException( "Error: no CallbackHandler available " + "to collect authentication information");
}
NameCallback nc = new NameCallback( "User name: ", "guest");
PasswordCallback pc = new PasswordCallback( "Password: ", false);
Callback[] callbacks = { nc, pc };
String username = null;
String password = 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;
}
}
Here is my security domain in jboss-app.xml placed in my ear file:
<jboss-app xmlns="http://www.jboss.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="7.0" xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee ">
<security-domain>testApp</security-domain>
</jboss-app>
Here is my new security domain I added to standalone.xml
<security-domain name="testApp" cache-type="default">
<authentication>
<login-module code="com.app.module.products.jboss.security.login.CustomLoginModule" flag="required " module="testApp.ear">
<module-option name="password-stacking" value="useFirstPass"/>
<module-option name="realm" value="ApplicationRealm"/>
</login-module>
</authentication>
</security-domain>
And:
<security-realm name="ApplicationRealm">
<authentication>
<jaas name="testApp"/>
</authentication>
</security-realm>
Using this configuration, when i try to launh client application, I am getting below exception at client side:
Caused by: javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed:
at org.jboss.remoting3.remote.ClientConnectionOpenListener.allMechanismsFailed(ClientConnectionOpenListener.java:113)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:443)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:242)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:72)
at org.xnio.channels.TranslatingSuspendableChannel.handleReadable(TranslatingSuspendableChannel.java:189)
at org.xnio.channels.TranslatingSuspendableChannel$1.handleEvent(TranslatingSuspendableChannel.java:103)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:72)
at org.xnio.nio.NioHandle.run(NioHandle.java:90)
at org.xnio.nio.WorkerThread.run(WorkerThread.java:198)
at ...asynchronous invocation...(Unknown Source)
at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:270)
at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:251)
at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:349)
at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:333)
at org.jboss.naming.remote.client.EndpointCache$EndpointWrapper.connect(EndpointCache.java:105)
at org.jboss.naming.remote.client.HaRemoteNamingStore.failOverSequence(HaRemoteNamingStore.java:197)
... 26 more
with no error at server console.
If i remove jaas security from ApplicationRealm in standalone.xml and provide below configuration:
<security-realm name="ApplicationRealm">
<server-identities>
<!-- Replace this with either a base64 password of your own, or use a vault with a vault expression -->
<secret value="cGFzc3dvcmQtMTIzNA=="/>
</server-identities>
<authentication>
<local default-user="$local" 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>
Application is able to connect with server.
Please guide me what steps i am missing here to invoke my custom login module?