JBoss AS 7 Custom Login Module never called

1k views Asked by At

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?

0

There are 0 answers