Access Manager contains a sample exercise for integrating a custom authentication module with files that have already been created. This sample illustrates the steps for integrating an authentication module into the Access Manager deployment. All the files needed to compile, deploy and run the sample authentication module can be found in the following directory:
AccessManager-base/SUNWam/samples/authentication/providers
The following sections will use files from this sample as example code:
<PRODUCT_DIR> setting on different Platforms:
Solaris Sparc/x86: <PRODUCT_DIR> = base-directory/SUNWam
Linux: <PRODUCT_DIR> = base-directory/sun/identity
Windows 2000: <PRODUCT_DIR> = base-directory
Use the AMLoginModule SPI to write your own sample login module.
Implementing the LoginModule Interface.
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:
init()
process()
getPrincipal()
For detailed descriptions, syntax, and parameters, see the Sun Java System Access Manager 7.1 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)
If you are writing your own Custom Authentication module based on the AMLoginModule SPI or a pure JAAS module, then you can skip this step. Otherwise, after writing the sample Login Module, compile and deploy the sample found under AccessManager-base/samples/authentication/spi/providers.
Set the following environment variables.
These variables will be used to run the gmake command. You can also set these variables in the Makefile. This Makefile is in the following directory: AccessManager-base /samples/authentication/spi/providers.
JAVA_HOME: Set this variable to your installation of JDK. The JDK should be version 1.3.1_06 or higher.
CLASSPATH: Set this variable to refer to am_services.jar which can be found in the Idetnity_base/lib directory. Include jaas.jar in your classpath if you are using JDK version less than JDK1.4
BASE_DIR: Set this variable to the directory where the Access Manager is installed.
BASE_CLASS_DIR: Set this variable to the directory where all the Sample compiled classes are located.
JAR_DIR: Set this variable to the directory where the JAR files of the Sample compiled classes will be created.
In the AccessManager-base/samples/authentication/spi/providers directory, run gmake.
Copy LoginModuleSample.jar from JAR_DIR to AccessManager-base/web-src/services/WEB-INF/lib .
Copy LoginModuleSample.xml from AccessManager-base /samples/authentication/spi/providers to AccessManager-base /web-src/services/config/auth/default .
Redeploy the amserver.war file.
In AccessManager-base/bin/amsamplesilent, set Deploy Level variable as follows:
DEPLOY_LEVEL=21
In AccessManager-base/bin/amsamplesilent, set container-related environment variables.
On Sun Java System Web Server 6.1, where /amserver is the default DEPLOY_URI:
SERVER_HOST=WebServer-hostName SERVER_PORT=WebServer-portNumber SERVER_PROTOCOL=[http | https] SERVER_DEPLOY_URI=/amserver WEB_CONTAINER=WS6 WS61_INSTANCE=https-$SERVER_HOST WS61_HOME= WebServer-base-directory WS61_PROTOCOL=$SERVER_PROTOCOL WS61_HOST=$SERVER_HOST WS61_PORT=$SERVER_PORT WS61_ADMINPORT=WebServer-adminPortWS61_ADMIN=WebServer-adminUserName
On Sun Java System Application Server 7.0, where /amserver is the default DEPLOY_URI:
SERVER_HOST=ApplicationServer-hostName SERVER_PORT=ApplicationServer-portNumber SERVER_PROTOCOL=[http | https] SERVER_DEPLOY_URI=/amserver WEB_CONTAINER=AS7 AS70_HOME=/opt/SUNWappserver7 AS70_PROTOCOL=$SERVER_PROTOCOL AS70_HOST=$SERVER_HOST AS70_PORT=$SERVER_PORT AS70_ADMINPORT=4848 AS70_ADMIN=admin AS70_ADMINPASSWD=ApplicationServer-adminPassword AS70_INSTANCE=server1 AS70_DOMAIN=domain1 AS70_INSTANCE_DIR=/var/opt/SUNWappserver7/domains/ ${AS70_DOMAIN:-domain1}/${AS70_INSTANCE:-server1} AS70_DOCS_DIR=/var/opt/SUNWappserver7/domains/${AS70_DOMAIN:-domain1}/ ${AS70_INSTANCE:-server1}/docroot #If Application Server is SSL Enabled then set the following: #AS70_IS_SECURE=true #SSL_PASSWORD=SSLpassword
On other supported platforms:
Set platform-specific variables as is appropriate for the container.
Redeploy the services web application by running the following command:
AccessManager-base/bin/amconfig -s AccessManager-base/bin/amsamplesilent
Restart the container instance.
Web Server example:
/WebServer-base-directory/ https-WebServer-instanceName/restart
Application Server example:
/var/opt/SUNWappserver7/domains/${AS70_DOMAIN:-domain1}/ ${AS70_INSTANCE:-server1}/bin/restartserv
Once you’ve compiled and deployed the login module, you must load the login module into Access Manager. You can load the login module by using either the Access Manager administration console, or by using the amadmin command.
Login to Access Manager Console as amadmin, using the URL:
http://host.domain:port/Console-Deploy-URL
Click Configuration.
In the Configuration tab, under Authentication, click Core.
Add class file name com.iplanet.am.samples.authentication.spi.providers. LoginModuleSample to the Pluggable Authentication Modules Classes list.
Click Save.
Write a sample XML file as shown in To Load the Login Module Using the Command Line, which will add the LoginModuleSample authentication module entry into the allowed modules and an authenticators list.
<!-- Copyright (c) 2003 Sun Microsystems, Inc. All rights reserved Use is subject to license terms. --> <!DOCTYPE Requests PUBLIC "-//iPlanet//iDSAME 5.0 Admin CLI DTD//EN" "jar://com/iplanet/am/admin/cli/amAdmin.dtd" > <Requests> <SchemaRequests serviceName="iPlanetAMAuthService" SchemaType="Global"> <AddDefaultValues> <AttributeValuePair> <Attribute name="iplanet-am-auth-authenticators"/> <Value>com.iplanet.am.samples.authentication.spi.providers. LoginModuleSample</Value> </AttributeValuePair> </AddDefaultValues> </SchemaRequests> </Requests> |
Use amadmin to load sample.xml:
<AMADMIN> --runasdn uid=amAdmin,ou=People,<root_suffix> --password <password> --data sample.xml
Solaris Sparc/x86: AMADMIN = <PRODUCT_DIR>/bin/amadmin
On W2K: AMADMIN = <PRODUCT_DIR>\\bin\\amadmin
This sections provides instructions for running the login module on Solaris and on Windows platforms.
Use the following URL to log in to Access Manager console as amAdmin:
http://host.domain:port/Console-Deploy-URI
Click Identity Management, and in the Identity Management view select your organization.
From the View menu, select Services.
In the navigation frame, under Authentication, click Core.
SelectLoginModuleSample to add it to the list of highlighted modules in Organization Authentication Modules.
Make sure LDAP module is also selected. If not selected, you will not be able to login to Access Manager Console. You can use Control + mouse click to add additional modules.
Click Save.
Log out.
Enter the following URL:
http://host.domain:port/Service-Deploy-URI/UI/Login?module=LoginModuleSample
If you choose to use an organization other than the default, be sure to specify that in the URL using the org parameter.
Set the following environment variables. These variables will be used to run the make command. You can also set these variables in the Makefile.
This Makefile is in the same directory as the Login Module Sample program files: AccessManager-base\samples\authentication\spi\providers
JAVA_HOME: Set this variable to your installation of JDK. The JDK should be version 1.3.1_06 or higher.
BASE: Set this variable to base-directory
CLASSPATH: Set this variable to refer to am_services.jar which can be found in the base-directory\lib directory. Include jaas.jar in your classpath if you are using JDK version less than JDK1.4
BASE_CLASS_DIR: Set this variable to the directory where all the Sample compiled classes are located.
JAR_DIR: Set this variable to the directory where the JAR files of the Sample compiled classes will be created.
In the base-directory\samples\authentication\spi\providers directory, run the make command.
Copy LoginModuleSample.jar from JAR_DIR to AccessManager-base\web-src\services\WEB-INF\lib
In the Web Container from which this sample has to run, update the classpath with LoginModuleSample.jar.
Update server.xml with the new classpath and server.xml locations:
Sun Java System Web Server : <WS-install-dir>\https-<WS-instance-name>\config\server.xml
Sun Java System Application Server: <AS-install-dir>\domain<appserver domain><appserver_instance>\config\server.xml
Example:<AS-install-dir>\domain\domain1\server1\config\server.xml
Copy LoginModuleSample.xml from base-directory \samples\authentication\spi\providers to base-directory\web-src\services\config\auth\default.
Restart the web container
Web Server: <WS-home-dir>\https-<WS-instance-name>\restart
Application Server: AppServer-home-dir>\domains\<domain name><server_instance>\bin\restartserv