-
Notifications
You must be signed in to change notification settings - Fork 30
/
TSClientAuthConfig.java
265 lines (234 loc) · 10.7 KB
/
TSClientAuthConfig.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
/*
* Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package ee.jakarta.tck.authentication.test.basic.sam.config;
import ee.jakarta.tck.authentication.test.basic.servlet.JASPICData;
import ee.jakarta.tck.authentication.test.common.logging.server.TSLogger;
import jakarta.security.auth.message.AuthException;
import jakarta.security.auth.message.MessageInfo;
import jakarta.security.auth.message.config.ClientAuthContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.xml.soap.MimeHeaders;
import jakarta.xml.soap.Name;
import jakarta.xml.soap.SOAPBody;
import jakarta.xml.soap.SOAPElement;
import jakarta.xml.soap.SOAPEnvelope;
import jakarta.xml.soap.SOAPException;
import jakarta.xml.soap.SOAPMessage;
import jakarta.xml.soap.SOAPPart;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
/**
*
* @author Raja Perumal
*/
public class TSClientAuthConfig implements jakarta.security.auth.message.config.ClientAuthConfig {
private static String messageLayer;
private static String appContext;
private static CallbackHandler callbackHandler;
private static TSLogger logger;
private Map properties = null;
/**
* Creates a new instance of ClientAuthConfigImpl
*/
public TSClientAuthConfig(String layer, String applicationCtxt, CallbackHandler cbkHandler, Map props) {
messageLayer = layer;
appContext = applicationCtxt;
callbackHandler = cbkHandler;
properties = props;
}
public TSClientAuthConfig(String layer, String applicationCtxt, CallbackHandler cbkHandler, Map props, TSLogger tsLogger) {
this(layer, applicationCtxt, cbkHandler, props);
logger = tsLogger;
String str = "TSClientAuthConfig called for layer=" + layer + " : appContext=" + applicationCtxt;
logger.log(Level.INFO, str);
}
/**
* Get the authentication context identifier corresponding to the request and response objects encapsulated in
* messageInfo.
*
* @param messageInfo a contextual Object that encapsulates the client request and server response objects.
*
* @return the operation identifier related to the encapsulated request and response objects, or null.
*
* @throws IllegalArgumentException if the type of the message objects incorporated in messageInfo are not compatible
* with the message types supported by this authentication context configuration object.
*/
@Override
public String getAuthContextID(MessageInfo messageInfo) {
String rval = null;
logger.log(Level.INFO, "TSClientAuthConfig.getOperation called");
if (messageLayer.equals(JASPICData.LAYER_SOAP)) {
return getOpName((SOAPMessage) messageInfo.getRequestMessage());
} else if (messageLayer.equals(JASPICData.LAYER_SERVLET)) {
HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage();
rval = request.getServletPath() + " " + request.getMethod();
return rval;
} else
return null;
}
private String getOpName(SOAPMessage message) {
if (message == null) {
return null;
}
String rvalue = null;
// first look for a SOAPAction header.
// this is what .net uses to identify the operation
MimeHeaders headers = message.getMimeHeaders();
if (headers != null) {
String[] actions = headers.getHeader("SOAPAction");
if (actions != null && actions.length > 0) {
rvalue = actions[0];
if (rvalue != null && rvalue.equals("\"\"")) {
rvalue = null;
}
}
}
// if that doesn't work then we default to trying the name
// of the first child element of the SOAP envelope.
if (rvalue == null) {
Name name = getName(message);
if (name != null) {
rvalue = name.getLocalName();
}
}
return rvalue;
}
private Name getName(SOAPMessage message) {
Name rvalue = null;
SOAPPart soap = message.getSOAPPart();
if (soap != null) {
try {
SOAPEnvelope envelope = soap.getEnvelope();
if (envelope != null) {
SOAPBody body = envelope.getBody();
if (body != null) {
Iterator<?> it = body.getChildElements();
while (it.hasNext()) {
Object o = it.next();
if (o instanceof SOAPElement) {
rvalue = ((SOAPElement) o).getElementName();
break;
}
}
}
}
} catch (SOAPException se) {
logger.log(Level.INFO, "WSS: Unable to get SOAP envelope");
}
}
return rvalue;
}
/**
* Causes a dynamic anthentication context configuration object to update the internal state that it uses to process
* calls to its <code>getAuthContext</code> method.
*
* @exception AuthException if an error occured during the update.
*
* @exception SecurityException if the caller does not have permission to refresh the configuration object.
*/
@Override
public void refresh() {
}
/**
* Get the message layer name of this authentication context configuration object.
*
* @return the message layer name of this configuration object, or null if the configuration object pertains to an
* unspecified message layer.
*/
@Override
public String getMessageLayer() {
return messageLayer;
}
/**
* Get the application context identifier of this authentication context configuration object.
*
* @return the String identifying the application context of this configuration object or null if the configuration
* object pertains to an unspecified application context.
*/
@Override
public String getAppContext() {
return appContext;
}
/**
* Get a ClientAuthContext instance from this ClientAuthConfig.
*
* <p>
* The implementation of this method returns a ClientAuthContext instance that encapsulates the ClientAuthModules used
* to secure and validate requests/responses associated with the given <i>operation</i>.
*
* <p>
* Specifically, this method accesses this ClientAuthConfig object with the argument <i>operation</i> to determine the
* ClientAuthModules that are to be encapsulated in the returned ClientAuthContext instance.
*
* <P>
* The ClientAuthConfig object establishes the request and response MessagePolicy objects that are passed to the
* encapsulated modules when they are initialized by the returned ClientAuthContext instance. It is the modules'
* responsibility to enforce these policies when invoked.
*
* @param operation an operation identifier used to index the provided <i>config</i>, or null. This value must be
* identical to the value returned by the <code>getOperation</code> method for all <code>MessageInfo</code> objects
* passed to the <code>secureRequest</code> method of the returned ClientAuthContext.
*
* @param clientSubject a Subject that represents the source of the service request to be secured by the acquired
* authentication context. The principal and/or credentials of the Subject may be used to select or acquire the
* authentication context. If the Subject is not null, additional Principals or credentials (pertaining to the source of
* the request) may be added to the Subject. A null value may be passed to for this parameter.
*
* @param properties a Map object that may be used by the caller to augment the properties that will be passed to the
* encapsulated modules at module initialization. The null value may be passed for this parameter.
*
* @return a ClientAuthContext instance that encapsulates the ClientAuthModules used to secure and validate
* requests/responses associated with the given <i>operation</i>, or null (indicating that no modules are configured).
*
* @exception AuthException if this operation fails.
*/
@Override
public ClientAuthContext getAuthContext(String operation, Subject clientSubject, Map properties) throws AuthException {
// Copy properties that are passed in this method to this.properties
//
// Note: this.properties is obtained from the Provider which gets those
// properties during provider registration time from the factory.
this.properties.putAll(properties);
try {
String logStr = "TSClientAuthConfig.getAuthContext: layer=" + messageLayer + " : appContext=" + appContext;
logger.log(Level.INFO, logStr);
logger.log(Level.INFO, "TSClientAuthConfig.getAuthContext: layer=" + messageLayer + " : appContext=" + appContext
+ " operationId=" + operation);
ClientAuthContext clientAuthContext = new TSClientAuthContext(messageLayer, appContext, callbackHandler, operation,
clientSubject, this.properties, logger);
logStr = "TSClientAuthConfig.getAuthContext: returned non-null" + " ClientAuthContext for operationId=" + operation;
logger.log(Level.INFO, logStr);
return clientAuthContext;
} catch (Exception e) {
throw new AuthException(e.getMessage());
}
}
/**
* Used to determine whether the authentication context configuration object encapsulates any protected authentication
* contexts.
*
* @return true if the configuration object encapsulates at least one protected authentication context. Otherwise, this
* method returns false.
*/
@Override
public boolean isProtected() {
// To verify protected code path, always return true.
return true;
}
}