Creating a Custom JBoss Login Module

This tutorial is a simple walk through the creation of a custom Login module with JBoss EAP 6 / WildFly application server.

 

The PicketBox library ships with a set of ready to run login modules which can be used for a variety of contexts such as File based, Database or LDAP authentication. Sometimes you will need to create your own Login Module and this tutorial will guide you through the steps needed to do it.

The starting point will be one the existing login modules, in our case we will extend the org.jboss.security.auth.spi.UsernamePasswordLoginModule that is equipped with PicketLink module:

package com.mastertheboss;

import java.security.acl.Group;
import java.util.Map;

import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;

import org.jboss.security.SimpleGroup;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.auth.spi.UsernamePasswordLoginModule;

 
public class BasicLoginModule extends UsernamePasswordLoginModule {

    public void initialize(Subject subject, CallbackHandler callbackHandler,
            Map sharedState,
            Map options) {

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

    /**

     * (required) The UsernamePasswordLoginModule modules compares the result of this

     * method with the actual password.

     */

    @Override
    protected String getUsersPassword() throws LoginException {

        System.out.format("MyLoginModule: authenticating user '%s'\n", getUsername());

        // Lets pretend we got the password from somewhere and that it's, by a chance, same as the username

        String password = super.getUsername();

        // Let's also pretend that we haven't got it in plain text but encrypted

        // (the encryption being very simple, namely capitalization)

        password = password.toUpperCase();

        return password;

    }

    @Override
    protected boolean validatePassword(String inputPassword, String expectedPassword) {

        // Let's encrypt the password typed by the user in the same way as the stored password

        // so that they can be compared for equality.

        String encryptedInputPassword = (inputPassword == null)? null : inputPassword.toUpperCase();

        System.out.format("Validating that (encrypted) input psw '%s' equals to (encrypted) '%s'\n"

                , encryptedInputPassword, expectedPassword);

		// Password check strategy: find the password from your storage (e.g. DB) and check that it's equal		

        // with inputPassword. We always return true, meaning password check will be skipped

        return true;

    }

    /**

     * (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 };

    }

   

}

Here, the initialize method is used to gather some module options which can be included in your login module.

The most important parts are the validatePassword method and the getRoleSets.

  • validatePassword does the password checking job, as commented in the code
  • getRoleSets finds the role for the user, once that password checking was successfull. In this example we have granted the Manager role to the user.

Now package the module in an archive say LoginModule.jar and deploy it as a module on the application server.

Here is the module.xml file which we will use for the module named basicloginmodule:

<module xmlns="urn:jboss:module:1.1" name="basicloginmodule">

  <resources>
    <resource-root path="LoginModule.jar"/>
  </resources>


  <dependencies>

    <module name="org.picketbox"/>

    <module name="javax.api"/>

  </dependencies>

</module>

Now last step will be including the security domain for this module in your server configuration:

<security-domain name="simple-auth" cache-type="default">

    <authentication>

        <login-module code="com.mastertheboss.BasicLoginModule" flag="required" module="login"/>

    </authentication>

</security-domain>

Follow us on Twitter