WebSphere® Application Server supports plugging
in a custom Java™ Authentication and Authorization
Service (JAAS) login module before or after the WebSphere Application
Server system login module. However, WebSphere Application
Server does not support the replacement of the WebSphere Application
Server system login modules, which are used to create the WSCredential
credential and WSPrincipal principal 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 Platform,
Enterprise Edition (Java EE) application.
About this task
WebSphere Application Server enables you
to propagate information downstream that is added to the Subject by
a custom login module. For more information, see Security attribute propagation. To determine
which login configuration to use for plugging in your custom login
modules, see the descriptions of the login configurations that are located in
the System login configuration entry settings for Java Authentication and Authorization Service.
WebSphere Application Server 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
> Global security. Under Java Authentication
and Authorization Service, click System logins.
Procedure
- 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.
Attention: 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.
Attention: 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 by using the following command:
wsadmin -f sample.jacl
- Remove the current LTPA_WEB login configuration and all
of the login modules.
You can 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.
You
can use the following sample Jacl script to recover the original LTPA_WEB
configuration:
Attention: 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 WebSphere Application
Server 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 by 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 you 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.
Attention: 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, WebSphere Application Server runtime
code rejects the Subject to make security decisions.
AuthenLoginModule
uses the following code to initialize the callback array:
Attention: 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.
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.
Attention: 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, WebSphere Application
Server supports the trust association interface (TAI).
Other
credential types and information can be added to the caller Subject
during the authentication process by using a custom login module.
The third-party credentials in the caller Subject are managed by WebSphere Application Server as part of
the security context. The caller Subject is bound to the running thread
during the request processing. When a web or an Enterprise JavaBeans (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 that
is 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.