WebSphere Application Server - Express supports using a custom Java Authentication and Authorization Service (JAAS) login module before or after the WebSphere Application Server - Express system login module. However, WebSphere Application Server - Express does not support the replacement of the WebSphere Application Server - Express system login modules, which are used to create WSCredential and WSPrincipal in the Subject. By using a custom login module, you can either make additional authentication decisions or add information to the Subject to make additional, potentially finer-grained, authorization decisions inside a Java 2 Platform, Enterprise Edition (J2EE) application.
Lightweight Third Party Authentication (LTPA), the WebSphere Application Server - Express server-side authentication mechanism, is implemented as the JAAS LoginModule. The LTPA login configuration is defined in WebSphere Common Configuration Module (WCCM) model within the cell-level security.xml XML file and within the wsjaas.conf properties file. There are two sets of JAAS login configuration defined in the WCCM model: the application login configuration and the system login configuration. LTPA is defined in the system login configuration.
WebSphere Application Server - Express enables you to customize the LTPA system configuration. A new LTPA_WEB login configuration exists in the WCCM model, which is used exclusively by the Web container. The LTPA login configuration is used by the EJB container. The LTPA_WEB login configuration contains the com.ibm.ws.security.web.AuthenLoginModule module and the LTPA login configuration contains the com.ibm.ws.security.server.lm.ltpaLoginModule module. The new AuthenLoginModule is an enhanced ltpaLoginModule that can process the HttpServletRequest object, the HttpServletResponse object, and the Web application name that are passed in using the CallbackHandler.
WebSphere Application Server - Express exposes the server-side login configuration so that you may customize the LTPA authentication process. Both the LTPA login configuration and the LTPA_WEB login configuration enable you to add a custom LoginModule both before and after the ltpaLoginModule and the AuthenLoginModule. For example, you may add a LoginModule to perform principal or credential mapping function either before or after the authentication. In the Web configuration, a custom LoginModule may perform principal mapping using a combination of authenticated user name, application name, and URL patterns. WebSphere Application Server - Express does not allow you to rename nor remove the LTPA and LTPA_WEB login configurations.
WebSphere Application Server - Express Version 5.1.1 supports the modification of the system login configuration through the administrative console and by using the wsadmin scripting utility. To configure the system login configuration using the administrative console, click Security --> JAAS Configuration --> System logins.
In WebSphere Application Server - Express Version 5.1, the system login configuration is not exposed in the administrative console. However, you can modify the system login configuration with the wsadmin scripting utility. The following sample JACL script adds a customLoginModule into the Lightweight Third-party Authentication (LTPA) Web system login configuration:
# Open security.xml set sec [$AdminConfig getid /Cell:hillside/Security:/] # Locate systemLoginConfig set slc [$AdminConfig showAttribute $sec systemLoginConfig] set entries [lindex [$AdminConfig showAttribute $slc entries] 0] # Append a new LoginModule to LTPA_WEB foreach entry $entries { set alias [$AdminConfig showAttribute $entry alias] if {$alias == "LTPA_WEB"} { set newJAASLoginModuleId [$AdminConfig create JAASLoginModule $entry {{moduleClassName "com.ibm.ws.security.common.auth.module.proxy.WSLoginModuleProxy"}}] set newPropertyId [$AdminConfig create Property $newJAASLoginModuleId {{name delegate}{value "com.ABC.security.auth.CustomLoginModule"}}] $AdminConfig modify $newJAASLoginModuleId {{authenticationStrategy REQUIRED}} break } } # save the change $AdminConfig save
Note: The wsadmin scripting utility inserts a new object to the end of the list. To insert the custom LoginModule before the AuthenLoginModule, delete the AuthenLoginModule and then recreate it after inserting the custom LoginModule. Save the sample script into a file, sample.jacl, and run the sample script with the following command:
Wsadmin -f sample.jacl
You can use the following sample JACL script to remove the current LTPA_WEB login configuration and all the LoginModules:
# Open security.xml set sec [$AdminConfig getid /Cell:hillside/Security:/] # Locate systemLoginConfig set slc [$AdminConfig showAttribute $sec systemLoginConfig] set entries [lindex [$AdminConfig showAttribute $slc entries] 0] # Remove the LTPA_WEB login configuration foreach entry $entries { set alias [$AdminConfig showAttribute $entry alias] if {$alias == "LTPA_WEB"} { $AdminConfig remove $entry break } } # save the change $AdminConfig save
You can use the following sample JACL script to recover the original LTPA_WEB configuration:
# Open security.xml set sec [$AdminConfig getid /Cell:hillside/Security:/] # Locate systemLoginConfig set slc [$AdminConfig showAttribute $sec systemLoginConfig] set entries [lindex [$AdminConfig showAttribute $slc entries] 0] # Recreate the LTPA_WEB login configuration set newJAASConfigurationEntryId [$AdminConfig create JAASConfigurationEntry $slc {{alias LTPA_WEB}}] set newJAASLoginModuleId [$AdminConfig create JAASLoginModule $newJAASConfigurationEntryId {{moduleClassName "com.ibm.ws.security.common.auth.module.proxy.WSLoginModuleProxy"}}] set newPropertyId [$AdminConfig create Property $newJAASLoginModuleId {{name delegate}{value "com.ibm.ws.security.web.AuthenLoginModule"}}] $AdminConfig modify $newJAASLoginModuleId {{authenticationStrategy REQUIRED}} # save the change $AdminConfig save
The WebSphere Application Server - Express Version 5.1 ltpaLoginModule and AuthenLoginModule use the shared state to save state information so that custom LoginModules can modify the information. The ltpaLoginModule initializes the callback array in the login() method using the following code. The callback array is created by ltpaLoginModule only if an array is not defined in the shared state area. In the following code sample, the error handling code was removed to make the sample concise. If you insert a custom LoginModule before the ltpaLoginModule, custom LoginModule may follow the same style to save the callback into the shared state.
import com.ibm.wsspi.security.auth.callback.*; . . . Callback callbacks[] = null; if (!sharedState.containsKey(Constants.CALLBACK_KEY)) { callbacks = new Callback[3]; callbacks[0] = new NameCallback("Username: "); callbacks[1] = new PasswordCallback("Password: ", false); callbacks[2] = new WSCredTokenCallbackImpl("Credential Token: "); try { callbackHandler.handle(callbacks); } catch (java.io.IOException e) { . . . } catch (UnsupportedCallbackException uce) { . . . } sharedState.put(Constants.CALLBACK_KEY, callbacks); } else { callbacks = (Callback []) sharedState.get(Constants.CALLBACK_KEY); }
ltpaLoginModule and AuthenLoginModule generate both a WSPrincipal and a WSCredential object to represent the authenticated user identity and security credentials. The WSPrincipal and WSCredential objects also are saved in the shared state. A JAAS login uses a two-phase commit protocol. First, the login methods in login modules, which are configured in the login configuration, are called. Then, their commit methods are called. A custom LoginModule, which is inserted after the ltpaLoginModule and the AuthenLoginModule, can modify the WSPrincipal and WSCredential objects before they are committed. The WSCredential and WSPrincipal objects must exist in the Subject after the login is completed. Without these objects in the Subject, WebSphere Application Server - Express run-time code rejects the Subject when it is used to make any security decisions.
AuthenLoginModule uses the following code to initialize the callback array:
import com.ibm.websphere.security.auth.callback.*; import com.ibm.wsspi.security.auth.callback.*; ... Callback callbacks[] = null; if (!sharedState.containsKey(Constants.CALLBACK_KEY)) { callbacks = new Callback[6]; callbacks[0] = new NameCallback("Username: "); callbacks[1] = new PasswordCallback("Password: ", false); callbacks[2] = new WSCredTokenCallbackImpl( "Credential Token: "); callbacks[3] = new WSServletRequestCallback( "HttpServletRequest: "); callbacks[4] = new WSServletResponseCallback( "HttpServletResponse: "); callbacks[5] = new WSAppContextCallback( "ApplicationContextCallback: "); try { callbackHandler.handle(callbacks); } catch (java.io.IOException e) { . . . } catch (UnsupportedCallbackException uce { . . . } sharedState.put(Constants.CALLBACK_KEY, callbacks); } else { callbacks = (Callback []) sharedState.get(Constants.CALLBACK_KEY); }
Three more objects, which contain callback information for the login, are passed from the Web container to the AuthenLoginModule: a java.util.Map, a HttpServletRequest, and a HttpServletResponse object. These objects represent the Web application context. The WebSphere Application Server - Express Version 5.1 application context, java.util.Map object, contains the application name and the error page URL. You can obtain the application context, java.util.Map object, by calling the getContext() method on the WSAppContextCallback object. The java.util.Map object is created with the following deployment descriptor information:
import com.ibm.wsspi.security.auth.callback.*; . . . HashMap appContext = new HashMap(2); appContext.put(Constants.WEB_APP_NAME, web_application_name); appContext.put(Constants.REDIRECT_URL, errorPage);
The application name and the HttpServletRequest object may be read by the custom LoginModule to perform mapping functions. The error page of the form-based login may be modified by a custom LoginModule.
Other credential types and information can be added to the caller Subject during the authentication process using a custom LoginModule. The third-party credentials in the caller Subject are managed by WebSphere Application Server - Express as part of the security context. The caller Subject is bound to the thread of execution during the request processing. When a Web module is configured to use the caller identity, the user identity is propagated to the downstream service. WSCredential and any third-party credentials in the caller Subject are not propagated downstream. Instead, some of the information can be regenerated at the target server based on the propagated identity. Add third-party credentials to the caller Subject at the authentication stage. The caller Subject, which is returned from the WSSubject.getCallerSubject() method, is read-only and thus cannot be modified..