Use the AMLoginModule SPI to write your own sample login module.
The following are the default directories used in the sample exercise for the various platforms:
Solaris Sparc/x86: <PRODUCT_DIR> = base-directory/SUNWam
Linux: <PRODUCT_DIR> = base-directory/sun/identity
W2K: <PRODUCT_DIR> = base-directory
Create a Module properties XML file with the same name of the class (no package name) and use the extension .xml. You must create an XML file with this naming convention even if no states required
Based on this configuration file, the Authentication user interface will dynamically generate a login page.
You can define page states in the module properties file as shown in Creating a Module Properties File. Each callback element corresponds to one login page state. When an authentication process is invoked, Callback values will be generated from the user’s Login Module for each state. All login state definitions start with 1. The module controls the login process, and then determines what the next state is.
Auth_Module_Properties.dtd defines the data structure that will be used by each authentication module to specify its properties. Auth_Module_Properties.dtd provides definitions to initiate, construct and send required callbacks information to the Authentication graphical user interface. Auth_Module_Properties.dtd is stored in the <PRODUCT_DIR>/dtd directory.
<ModuleProperties moduleName="LoginModuleSample" version="1.0" > <Callbacks length="2" order="1" timeout="60" header="This is a sample login page"> <NameCallback> <Prompt> User Name </Prompt> </NameCallback> <NameCallback> <Prompt> Last Name </Prompt> </NameCallback> </Callbacks> <Callbacks length="1" order="2" timeout="60" header="You made it to page 2" > <PasswordCallback echoPassword="false" > <Prompt> Just enter any password </Prompt> </PasswordCallback> </Callbacks> </ModuleProperties> Module Configuration Sample
In this module configuration sample, page state one has two callbacks. The first callback is for user ID, and second is for Last Name. When the user fills in the callbacks, the following events occur:
The Callback values are sent to the module.
The process() routine validates the callback values.
The module writer sets the next page state to 2.
Page state 2 has one callback to request the user to enter a password. The process() routine is again called after the user submits the Callback values. If the module writer throws a LoginException, then an Authentication Failed page will be sent to the user. If no exception is thrown, the user is redirected to his or her default page.
After creating module configuration XML file, the next step is to write a Sample Principal class which implements java.security.Principal. The constructor takes the user’s username as an argument. If authentication is successful, the module will return this principal to Authentication framework. The Authentication framework populates a Subject with a SamplePrincipal representing the user.
AMLoginModule is an abstract class which implements JAAS LoginModule. AMLoginModule provides methods for accessing Access Manager services and the module XML configuration. Login Module writers must subclass AMLoginModule class and implement the following methods:
For detailed descriptions, syntax, and parameters, see the Sun Java System Access Manager 7 2005Q4 Java API Reference. The following sections provide some supporting information about these methods.
init() This is an abstract method, Module writer should implement to initialize this LoginModule with the relevant information. If this LoginModule does not understand any of the data stored in sharedState or options parameters, the data can be ignored. This method is called by a AMLoginModule after thisSampleLoginModule has been instantiated, and prior to any calls to its other public methods. The method implementation should store away the provided arguments for future use. The init method may additionally peruse the provided sharedState to determine what additional authentication state it was provided by other LoginModules, and may also traverse through the provided options to determine what configuration options were specified to affect the LoginModule’s behavior. It may save option values in variables for future use.
process() The process method is called to authenticate a Subject. This method implementation should perform the actual authentication. For example, it may cause prompting for a user name and password, and then attempt to verify the password against a password database. If your LoginModule requires some form of user interaction (retrieving a user name and password, for example), it should not do so directly. That is because there are various ways of communicating with a user, and it is desirable for LoginModules to remain independent of the different types of user interaction. Rather, the LoginModule’s process method should invoke the handle method of the CallbackHandler passed to this method to perform the user interaction and set appropriate results, such as the user name and password and the AMLoginModule internally passes the GUI an array of appropriate Callbacks, for example a NameCallback for the user name and a PasswordCallback for the password, and the GUI performs the requested user interaction and sets appropriate values in the Callbacks.
Consider the following points while writing the process() method:
Perform the authentication. If Authentication succeeded, save the principal who has successfully authenticated.
Return -1 if authentication succeeds, or throw a LoginException such as AuthLoginException if authentication fails or return relevant state specified in module configuration XML file
If multiple states are available to the user, the Callback array from a previous state may be retrieved by using the getCallbak(int state) methods. The underlying login module keeps the Callback from the previous states until the login process is completed.
If a module writer needs to substitute dynamic text in next state, the writer could use the getCallback() method to get the Callback for the next state, modify the output text or prompt, then call replaceCallback() to update the Callback array. This allows a module writer to dynamically generate challenges, passwords or user IDs. Each authentication session will create a new instance of your Login Module Java class. The reference to the class will be released once the authentication session has either succeeded or failed. It is important to note that any static data or reference to any static data in your Login module must be thread-safe.
getPrincipal() This method should be called once at the end of a successful authentication session. A login session is deemed successful when all pages in the Module properties XML file have been sent and the module has not thrown an exception. The method retrieves the authenticated token string that the authenticated user will be known by in the Access Manager environment.
If the custom authentication module requires or already uses a service configuration XML file:
The XML file should contain attribute schema for one of the following attributes: iplanet-am-auth-authModuleName-auth-level or lsunAMAuthauthModuleNameAuthLevel
The module Java file should invoke the following method in the init method implementation: public boolean setAuthLevel(int auth_level)