There's a more up-to-date version of this page in Chapter 16 of the OpenAM Developer's Guide.
Creating a Custom Authentication Module
|Custom Authentication Modules|
OpenAM comes complete with a wide variety of built-in custom authentication modules, but sometimes customer requirements step outside the functionality provided by the built-in modules. In these instances, it is time to consider writing your own custom authentication module. The OpenAM developer can use the source of the built-in modules as their starting point or start from scratch. If the customer requirement is a very close match to existing functionality then using a built-in module as a starting point will be a good idea. The OpenAM developer should start from scratch if the customer requirements does not match any of the built-in modules.
In this HowTo we look at how to create and configure custom authentication modules.
- Creating a Custom Authentication Module
- Requirements for Sample Authentication module
- Prepare your development environment
- Design your custom authentication module
- Implement your custom authentication module
- Compile your custom authentication module
- Install your custom authentication module
- Copy the jar file
- Copy the service properties file
- Copy the authentication module XML file
- Register the module and the service with OpenAM
- Configure your custom Authentication module
- Test your custom module
Requirements for Sample Authentication module
Our sample authentication module takes username and password as input from the user. This data along with a service specific attribute and the program logic is used to authenticate the user. During this process some errors can occur which will be shown to user in detail. All texts displayed during the authentication must be easily configurable and translatable.
In short - we have following requirements
- User will be asked for name and password
- Module has one specific attribute which needs to be configured via OpenAM web-interface
- The authentication UI is configurable and translatable
- Some errors have to be displayed to user in detail
Prepare your development environment
We will stick with using the basic complier in this HowTo to keep things simple. In order to compile your custom authentication module either on the command line or in your favourite IDE you will need the following OpenAM jar files.
In addition you will also require the J2EE Servlet API, you can obtain these from within your favourite container or here.
|If you are using tomcat|
If you use tomcat then you can find the Servlet API files in the
Design your custom authentication module
First important decision is to pick a name for our authentication module. We decide to call our module SampleAuth.
An OpenAM custom authentication module is comprised of the following components:
- Authentication logic (SampleAuth.java) which extends the com.sun.identity.authentication.spi.AMLoginModule abstract class
- Principal (SampleAuthPrincipal.java) which implements the java.security.Principal interface
- Callbacks XML file (SampleAuth.xml) which describes the states of authentication logic and the user input needed during those states
- Service configuration XML file (amAuthSampleAuth.xml) which defines how service is configured on OpenAM side
- Authentication module properties file (amAuthSampleAuth.properties)
The Callbacks XML file
The custom authentication module is designed to ask the user a series of questions in order assert their identity. The order and detail of these questions is set out in the Callbacks XML file. The structure of the XML file is defined in the
|Re-use, don't reinvent|
All of the built-in modules XML files are located in the
The custom authentication module
All custom authentication modules must extend from the com.sun.identity.authentication.spi.AMLoginModule abstract class. The abstract methods that must be implemented in the custom authentication module are listed below and the OpenAM Javadoc provides useful reference information.
init method is called once by OpenAM when the module is created. The
process method is called into when the user submits callbacks back via the Authentication interface. The
process method determines what happens next in the authentication process; success, failure or the next state (order) in the XML file. The
getPrincipal method is called by OpenAM and must return an implementation of the java.security.Principal interface.
|Authentication Module Life-cycle|
OpenAM does not reuse authentication module instances. This means that we can store information specific to the authentication process in the instance.
OpenAM Service and Properties file
The OpenAM administration will require a way to configure any custom authentication modules. OpenAM mandates that all authentication modules; built-in or custom are configured in the same way by means of an OpenAM service. At the bare minimum the service should contain an authentication level attribute.
The module can find the value of these attributes in the
The properties file is a standard Java properties file that contains the description of the attributes that will be displayed in the console.
Implement your custom authentication module
Sample Callback XML file
Simple callbacks file might look like:
This file defines authentication module SampleAuth with one possible state (order 1) in which 2 pieces of information are asked from the user. All strings that are used to draw the UI are typed into this file.
According to our requirements we need a little-bit more sophisticated callbacks file. We need dynamic text and we need error state. Following callbacks file achieves this:
- We need order 1 with 0 callbacks to change all UI strings for following orders. The trial-and-error shows that this dummy state is necessary to achieve dynamic UI-strings.
- The placeholders '#FOO BAR#' have no real meaning, this is just to show that those texts get replaced.
- The order 3 has attribute error set to "true". If the authentication module state machine reaches this order then the authentication has failed. The NameCallback is actually not used and not displayed to user, but the callbacks with length at least 1 is necessary, otherwise the OpenAM won't let us to substitute the header. So it's yet another hack forced upon us.
Sample Module Code
You will notice the code above allows the user "test" to log in with a password of "password". In order for this to work you will need to create a user called test in the OpenAM administration pages. This is because the code goes on to retrieve the user profile for the user, and if one doesn't exist, it will be this subsequent step that will fail and prevent you from logging in. In the OpenAM console, logged in as amadmin, select "Access Control", Top Level Realm, "Subjects" and click "New..."
Here is the code for the principal implementation
Service configuration XML
- The service must have a name: 'iPlanetAMAuth' + modulename + 'Service'
- The service must have a description
- i18nFileName refers to the properties file and i18nKey to the key in the properties file
- sampleauth-service-specific-attribute configurable via OpenAM is defined here
The 'iplanet-am-auth-sampleauth-auth-level' is the obligatory authentication level attribute. Here naming is very important. The name of the attribute must be: 'iplanet-am-auth-' + lowercase(modulename) + '-auth-level'. If the attribute name does not follow the pattern your authentication module will not function the way you want it to. (There is also a second naming convention - please refer to the source code )
It's a simple properties file. Be careful to match all the identifier.
Compile your custom authentication module
Next we need to compile the custom authentication module.
This will create our class file that we need to install into OpenAM. Next we should package the classes files up into a jar file.
Install your custom authentication module
Copy the jar file
We copy the jar file into the
WEB-INF/lib directory within the openam web application deployed into Tomcat.
Copy the service properties file
We copy the properties file into the
WEB-INF/classes directory within the openam web application deployed into Tomcat.
Copy the authentication module XML file
We copy the properties file into the
config/auth/default directory within the openam web application deployed into Tomcat.
Register the module and the service with OpenAM
ssoadm command to register the service and the module with OpenAM. The service can only be registered with OpenAM using
Note the service definition file is only needed for creating the service. When calling
ssoadm create-svc, be sure to pass the full path to your service definition file.
Also following subcommands might be useful to you during the testing: delete-auth-cfgs, delete-auth-instances, delete-svc, list-auth-cfgs, list-auth-instances, remove-svc-realm, show-auth-modules, show-realm-svcs, unregister-auth-module, update-svc
It is a good idea at this point to restart Tomcat (or whatever container you are using) to ensure the Authentication Module and service definition can be loaded.
Configure your custom Authentication module
Log into the Console and navigate to
Access Control >> Realm >> Authentication and click
Authentication modules. Name your module and select the custom authentication module type from the list. Click
OK. You should now see your custom module listed, you can select it and configure it as appropriate.
Test your custom module
The final step is to test out your custom authentication module. To do this you just need to login successfully to the realm where the custom authentication module is configured. This URL should do the trick:
You should be presented with the login screen and asked for the credentials required by your custom authentication module.