How to create 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.
Note: If you want to develop a custom login module on the latest security infrastructure (Elytron) we recommend checking also this tutorial: How to create a custom Elytron Realm
Getting Started with PicketBox Login Modules
PicketBox framework 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.
Packaging the Module
Next, 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>
Recommended Articles
Create a Custom MongoDB Login Module for JAAS Authentication with WildFly or JBoss AS 7
Learn how to create a custom login module that uses MongoDB for performing JAAS authentication in this step-by-step guide.
Connect WildFly/JBoss EAP to OpenLDAP Directory Service Using PicketBox Security Framework
Learn how to connect WildFly/EAP to OpenLDAP directory service using PicketBox Security Framework. For more recent configuration, check out our guide on configuring an Elytron LDAP Realm.
PicketBox Security Framework Overview and Migration to Elytron - WildFly
Learn about PicketBox security framework, its deprecation in newer WildFly versions, and how to migrate to the recommended Elytron. #WildFly #JavaSecurity #Elytron
Create a Custom Elytron Realm in WildFly 31: A Step-by-Step Guide
Learn how to create a custom realm in Elytron, a modern replacement for legacy Login Modules, with this comprehensive tutorial. Get started with creating a custom realm using WildFly 31 and configuring it to store user credentials.