Customize a server-side Java Authentication and Authorization Service authentication and login configuration
WebSphere Application Server supports plugging in a custom JAAS login module before or after the WAS system login module. However, WAS does not support the replacement of the WAS system login modules, which are used to create the WSCredential credential and WSPrincipal principal in the Subject. By using a custom login module, we can either make additional authentication decisions or add information to the Subject to make additional, potentially finer-grained, authorization decisions inside a Java EE application.
WAS enables us to propagate information downstream that is added to the Subject by a custom login module. See Security attribute propagation. To determine which login configuration to use for plugging in our custom login modules, see the descriptions of the login configurations located in the System login configuration entry settings for JAAS.
WAS supports the modification of the system login configuration through the administrative console and using the wsadmin scripting utility. To configure system login configuration using the administrative console, click Security > Global security. Under Java Authentication and Authorization Service, click...
System logins.
Tasks
- Configure a system login configuration.
Refer to the following code sample to configure a system login configuration using the wsadmin tool. The following sample Jacl script adds a custom login module into the Lightweight Third-party Authentication (LTPA) web system login configuration.
Lines 32, 33, and 34 in the following code samples are split into two lines.
1. ######################################### 2. # 3. # Open security.xml 4. # 5. ######################################### 6. 7. 8. set sec [$AdminConfig getid /Cell:hillside/Security:/] 9. 10. 11. ######################################### 12. # 13. # Locate systemLoginConfig 14. # 15. ######################################### 16. 17. 18. set slc [$AdminConfig showAttribute $sec systemLoginConfig] 19. 20. set entries [lindex [$AdminConfig showAttribute $slc entries] 0] 21. 22. 23. ######################################### 24. # 25. # Append a new LoginModule to LTPA_WEB 26. # 27. ######################################### 28. 29. foreach entry $entries { 30. set alias [$AdminConfig showAttribute $entry alias] 31. if {$alias == "LTPA_WEB"} { 32. set newJAASLoginModuleId [$AdminConfig create JAASLoginModule $entry {{moduleClassName "com.ibm.ws.security.common.auth.module.proxy.WSLoginModuleProxy"}}] 33. set newPropertyId [$AdminConfig create Property $newJAASLoginModuleId {{name delegate}{value "com.ABC.security.auth.CustomLoginModule"}}] 34. $AdminConfig modify $newJAASLoginModuleId {{authenticationStrategy REQUIRED}} 35. break 36. } 37. } 38. 39. 40. ######################################### 41. # 42. # save the change 43. # 44. ######################################### 45. 46. $AdminConfig save 47.The wsadmin scripting utility inserts a new object to the end of the list. To insert the custom login module before the AuthenLoginModule login module, delete the AuthenLoginModule login module and recreate it after inserting the custom login module. Save the sample script into a sample.jacl file, and run the sample script using the following command:
wsadmin -f sample.jacl- Remove the current LTPA_WEB login configuration and all of the login modules.
Use the following sample Jacl script to remove the current LTPA_WEB login configuration and all the login modules:
48. ######################################### 49. # 50. # Open security.xml 51. # 52. ######################################### 53. 54. 55. set sec [$AdminConfig getid /Cell:hillside/Security:/] 56. 57. 58. ######################################### 59. # 60. # Locate systemLoginConfig 61. # 62. ######################################### 63. 64. 65. set slc [$AdminConfig showAttribute $sec systemLoginConfig] 66. 67. set entries [lindex [$AdminConfig showAttribute $slc entries] 0] 68. 69. 70. ######################################### 71. # 72. # Remove the LTPA_WEB login configuration 73. # 74. ######################################### 75. 76. foreach entry $entries { 77. set alias [$AdminConfig showAttribute $entry alias] 78. if {$alias == "LTPA_WEB"} { 79. $AdminConfig remove $entry 80. break 81. } 82. } 83. 84. 85. ######################################### 86. # 87. # save the change 88. # 89. ######################################### 90. 91. $AdminConfig save- Recover the original LTPA_WEB configuration.
Use the following sample Jacl script to recover the original LTPA_WEB configuration:
Lines 122, 124, and 126 in the following code samples are split into two or more lines for illustrative purposes only.
92. ######################################### 93. # 94. # Open security.xml 95. # 96. ######################################### 97. 98. 99. set sec [$AdminConfig getid /Cell:hillside/Security:/] 100. 101. 102. ######################################### 103. # 104. # Locate systemLoginConfig 105. # 106. ######################################### 107. 108. 109. set slc [$AdminConfig showAttribute $sec systemLoginConfig] 110. 111. set entries [lindex [$AdminConfig showAttribute $slc entries] 0] 112. 113. 114. 115. ######################################### 116. # 117. # Recreate the LTPA_WEB login configuration 118. # 119. ######################################### 120. 121. 122. set newJAASConfigurationEntryId [$AdminConfig create JAASConfigurationEntry $slc {{alias LTPA_WEB}}] 123. 124. set newJAASLoginModuleId [$AdminConfig create JAASLoginModule $newJAASConfigurationEntryId {{moduleClassName "com.ibm.ws.security.common.auth.module.proxy.WSLoginModuleProxy"}}] 125. 126. set newPropertyId [$AdminConfig create Property $newJAASLoginModuleId {{name delegate}{value "com.ibm.ws.security.web.AuthenLoginModule"}}] 127. 128. $AdminConfig modify $newJAASLoginModuleId {{authenticationStrategy REQUIRED}} 129. 130. 131. ######################################### 132. # 133. # save the change 134. # 135. ######################################### 136. 137. $AdminConfig save- Have the ltpaLoginModule initialize the callback array in the login method.
The WAS Version ltpaLoginModule and AuthenLoginModule login modules use the shared state to save state information so that custom login modules can modify the information. The ltpaLoginModule login module initializes the callback array in the login method using the following code. The callback array is created by the ltpaLoginModule login module only if an array is not defined in the shared state area. In the following code sample, the error handling code is removed to make the sample concise. If we insert a custom login module before the ltpaLoginModule login module, the custom login module might follow the same style to save the callback into the shared state.
In the following code sample, several lines of code are split into two lines for illustrative purposes only.
138. Callback callbacks[] = null; 139. if (!sharedState.containsKey( com.ibm.wsspi.security.auth.callback.Constants. CALLBACK_KEY)) { 140. callbacks = new Callback[3]; 141. callbacks[0] = new NameCallback("Username: "); 142. callbacks[1] = new PasswordCallback("Password: ", false); 143. callbacks[2] = new com.ibm.websphere.security.auth.callback. WSCredTokenCallbackImpl( "Credential Token: "); 144. try { 145. callbackHandler.handle(callbacks); 146. } catch (java.io.IOException e) { 147. . . . 148. } catch (UnsupportedCallbackException uce) { 149. . . . 150. } 151. sharedState.put( com.ibm.wsspi.security.auth.callback. Constants.CALLBACK_KEY, callbacks); 152. } else { 153. callbacks = (Callback []) sharedState.get ( com.ibm.wsspi.security.auth.callback.Constants.CALLBACK_KEY); 154. }- Have the AuthenLoginModule initialize the callback array.
The ltpaLoginModule and AuthenLoginModule login modules generate both a WSPrincipal object 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 login module, which is inserted after the ltpaLoginModule and the AuthenLoginModule login modules, can modify the WSPrincipal and WSCredential objects before these objects are committed. The WSCredential and WSPrincipal objects must exist in the Subject after the login is completed. Without these objects in the Subject, WAS runtime code rejects the Subject to make security decisions.
AuthenLoginModule uses the following code to initialize the callback array:
In the following code sample, several lines of code are split into two lines for illustrative purposes only.
155. Callback callbacks[] = null; 156. if (!sharedState.containsKey( com.ibm.wsspi.security.auth. callback.Constants.CALLBACK_KEY)) { 157. callbacks = new Callback[6]; 158. callbacks[0] = new NameCallback("Username: "); 159. callbacks[1] = new PasswordCallback("Password: ", false); 160. callbacks[2] = new com.ibm.websphere.security.auth.callback. WSCredTokenCallbackImpl( "Credential Token: "); 161. callbacks[3] = new com.ibm.wsspi.security.auth.callback. WSServletRequestCallback( "HttpServletRequest: "); 162. callbacks[4] = new com.ibm.wsspi.security.auth.callback. WSServletResponseCallback( "HttpServletResponse: "); 163. callbacks[5] = new com.ibm.wsspi.security.auth.callback. WSAppContextCallback( "ApplicationContextCallback: "); 164. try { 165. callbackHandler.handle(callbacks); 166. } catch (java.io.IOException e) { 167. . . . 168. } catch (UnsupportedCallbackException uce { 169. . . . 170. } 171. sharedState.put( com.ibm.wsspi.security.auth.callback. Constants.CALLBACK_KEY, callbacks); 172. } else { 173. callbacks = (Callback []) sharedState.get(com.ibm.wsspi.security. auth.callback.Constants.CALLBACK_KEY); 174. }- Obtain the application context. Three more objects, which contain callback information for the login, are passed from the web container to the AuthenLoginModule login module: a java.util.Map, an HttpServletRequest, and an HttpServletResponse object. These objects represent the web application context.
We 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.
In the following code sample, several lines of code are split into two lines for illustrative purposes only.
175. HashMap appContext = new HashMap(2); 176. appContext.put( com.ibm.wsspi.security.auth.callback. Constants.WEB_APP_NAME,web_application_name); 177. appContext.put( com.ibm.wsspi.security.auth.callback.Constants. REDIRECT_URL,errorPage);
What to do next
The application name and the HttpServletRequest object might be read by the custom login module to perform mapping functions. The error page of the form-based login might be modified by a custom login module. In addition to the JAAS framework, WAS supports the trust association interface (TAI).
Other credential types and information can be added to the caller Subject during the authentication process using a custom login module. The third-party credentials in the caller Subject are managed by WAS as part of the security context. The caller Subject is bound to the running thread during the request processing. When a web or an EJB module is configured to use the caller identity, the user identity is propagated to the downstream service in an EJB request. The WSCredential credential 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 cannot be modified. For more information on the WSSubject subject, see Getting the caller subject from the thread for JAAS.
Subtopics
- Getting the caller subject from the thread for JAAS
The Caller subject (or "received subject") contains the user authentication information used in the call for this request. This subject is returned after issuing the WSSubject.getCallerSubject API to prevent replacing existing objects. The subject is marked read-only. This API can be used to get access to the WSCredential credential so that we can put or set data in the hashmap within the credential.- Getting the RunAs subject from the thread for JAAS
The RunAs subject or invocation subject contains the user authentication information for the RunAs mode set in the application deployment descriptor for this method.- Overriding the RunAs subject on the thread for JAAS
To extend the function provided by the JAAS APIs, we can set the RunAs subject or invocation subject with a different valid entry used for outbound requests on this running thread.- Revoking users from a cache for JAAS
In WAS, v5.0.2 and later, revocation of a user from the security cache using an MBean interface is supported.
Related:
Security attribute propagation Getting the caller subject from the thread for JAAS System login configuration entry settings for JAAS