1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.wss4j.dom.misc;
21
22 import java.security.Principal;
23 import java.security.cert.X509Certificate;
24 import java.util.List;
25
26 import javax.security.auth.callback.CallbackHandler;
27 import javax.xml.namespace.QName;
28
29 import org.apache.wss4j.common.crypto.Crypto;
30 import org.apache.wss4j.common.crypto.CryptoFactory;
31 import org.apache.wss4j.common.crypto.CryptoType;
32 import org.apache.wss4j.common.ext.WSSecurityException;
33 import org.apache.wss4j.common.principal.SAMLTokenPrincipal;
34 import org.apache.wss4j.common.principal.UsernameTokenPrincipal;
35 import org.apache.wss4j.common.saml.SAMLCallback;
36 import org.apache.wss4j.common.saml.SAMLUtil;
37 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
38 import org.apache.wss4j.common.token.BinarySecurity;
39 import org.apache.wss4j.common.token.X509Security;
40 import org.apache.wss4j.common.util.SOAPUtil;
41 import org.apache.wss4j.common.util.XMLUtils;
42 import org.apache.wss4j.dom.WSConstants;
43 import org.apache.wss4j.dom.common.SAML1CallbackHandler;
44 import org.apache.wss4j.dom.common.SAML2CallbackHandler;
45
46 import org.apache.wss4j.dom.common.UsernamePasswordCallbackHandler;
47 import org.apache.wss4j.dom.engine.WSSConfig;
48 import org.apache.wss4j.dom.engine.WSSecurityEngine;
49 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
50 import org.apache.wss4j.dom.handler.RequestData;
51 import org.apache.wss4j.dom.handler.WSHandlerResult;
52 import org.apache.wss4j.dom.message.WSSecHeader;
53 import org.apache.wss4j.dom.message.WSSecSAMLToken;
54 import org.apache.wss4j.dom.message.WSSecUsernameToken;
55 import org.apache.wss4j.dom.util.WSSecurityUtil;
56 import org.apache.wss4j.dom.validate.Credential;
57 import org.apache.wss4j.dom.validate.Validator;
58
59 import org.junit.jupiter.api.Test;
60 import org.w3c.dom.Document;
61
62 import static org.junit.jupiter.api.Assertions.assertNotNull;
63 import static org.junit.jupiter.api.Assertions.assertTrue;
64
65
66
67
68 public class PrincipalTest {
69 private static final org.slf4j.Logger LOG =
70 org.slf4j.LoggerFactory.getLogger(PrincipalTest.class);
71
72 private CallbackHandler callbackHandler = new UsernamePasswordCallbackHandler();
73
74
75
76
77 @Test
78 public void testUsernameToken() throws Exception {
79 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
80 WSSecHeader secHeader = new WSSecHeader(doc);
81 secHeader.insertSecurityHeader();
82
83 WSSecUsernameToken builder = new WSSecUsernameToken(secHeader);
84 builder.setUserInfo("wernerd", "verySecret");
85 Document signedDoc = builder.build();
86
87 if (LOG.isDebugEnabled()) {
88 String outputString =
89 XMLUtils.prettyDocumentToString(signedDoc);
90 LOG.debug(outputString);
91 }
92 WSHandlerResult results = verify(signedDoc, null);
93
94 Principal principal =
95 (Principal)results.getResults().get(0).get(WSSecurityEngineResult.TAG_PRINCIPAL);
96 assertTrue(principal instanceof UsernameTokenPrincipal);
97 assertTrue("wernerd".equals(principal.getName()));
98 UsernameTokenPrincipal userPrincipal = (UsernameTokenPrincipal)principal;
99 assertNotNull(userPrincipal.getCreatedTime());
100 assertNotNull(userPrincipal.getNonce());
101 assertNotNull(userPrincipal.getPassword());
102 assertTrue(userPrincipal.isPasswordDigest());
103 assertTrue(WSConstants.PASSWORD_DIGEST.equals(userPrincipal.getPasswordType()));
104 }
105
106
107
108
109
110 @Test
111 public void testTransformedUsernameToken() throws Exception {
112 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
113 WSSecHeader secHeader = new WSSecHeader(doc);
114 secHeader.insertSecurityHeader();
115
116 WSSecUsernameToken builder = new WSSecUsernameToken(secHeader);
117 builder.setUserInfo("wernerd", "verySecret");
118 Document signedDoc = builder.build();
119
120 if (LOG.isDebugEnabled()) {
121 String outputString =
122 XMLUtils.prettyDocumentToString(signedDoc);
123 LOG.debug(outputString);
124 }
125 WSHandlerResult results =
126 verify(signedDoc, new DummyValidator(), WSConstants.USERNAME_TOKEN, null);
127
128 Principal principal =
129 (Principal)results.getResults().get(0).get(WSSecurityEngineResult.TAG_PRINCIPAL);
130 assertTrue(principal instanceof SAMLTokenPrincipal);
131 assertTrue(principal.getName().contains("uid=joe"));
132 assertNotNull(((SAMLTokenPrincipal)principal).getToken());
133 }
134
135
136
137
138 @Test
139 public void testSAMLToken() throws Exception {
140 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
141 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
142 callbackHandler.setIssuer("www.example.com");
143
144 SAMLCallback samlCallback = new SAMLCallback();
145 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
146 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
147
148 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
149 WSSecHeader secHeader = new WSSecHeader(doc);
150 secHeader.insertSecurityHeader();
151
152 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
153
154 Document unsignedDoc = wsSign.build(samlAssertion);
155
156 if (LOG.isDebugEnabled()) {
157 String outputString =
158 XMLUtils.prettyDocumentToString(unsignedDoc);
159 LOG.debug(outputString);
160 }
161
162 WSHandlerResult results = verify(unsignedDoc, null);
163
164 List<WSSecurityEngineResult> samlResults =
165 results.getActionResults().get(WSConstants.ST_UNSIGNED);
166 WSSecurityEngineResult actionResult = samlResults.get(0);
167
168 SamlAssertionWrapper receivedSamlAssertion =
169 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
170 assertNotNull(receivedSamlAssertion);
171
172 Principal principal = (Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
173 assertTrue(principal instanceof SAMLTokenPrincipal);
174 assertTrue(principal.getName().contains("uid=joe"));
175 assertNotNull(((SAMLTokenPrincipal)principal).getToken());
176 }
177
178
179
180
181 @Test
182 public void testSAML2Token() throws Exception {
183 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
184 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
185 callbackHandler.setIssuer("www.example.com");
186
187 SAMLCallback samlCallback = new SAMLCallback();
188 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
189 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
190
191 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
192 WSSecHeader secHeader = new WSSecHeader(doc);
193 secHeader.insertSecurityHeader();
194
195 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
196
197 Document unsignedDoc = wsSign.build(samlAssertion);
198
199 if (LOG.isDebugEnabled()) {
200 String outputString =
201 XMLUtils.prettyDocumentToString(unsignedDoc);
202 LOG.debug(outputString);
203 }
204
205 WSHandlerResult results = verify(unsignedDoc, null);
206
207 List<WSSecurityEngineResult> samlResults =
208 results.getActionResults().get(WSConstants.ST_UNSIGNED);
209 WSSecurityEngineResult actionResult = samlResults.get(0);
210
211 SamlAssertionWrapper receivedSamlAssertion =
212 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
213 assertNotNull(receivedSamlAssertion);
214
215 Principal principal = (Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
216 assertTrue(principal instanceof SAMLTokenPrincipal);
217 assertTrue(principal.getName().contains("uid=joe"));
218 assertNotNull(((SAMLTokenPrincipal)principal).getToken());
219 }
220
221
222
223
224
225 @Test
226 public void testTransformedSAMLToken() throws Exception {
227 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
228 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
229 callbackHandler.setIssuer("www.example.com");
230
231 SAMLCallback samlCallback = new SAMLCallback();
232 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
233 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
234
235 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
236 WSSecHeader secHeader = new WSSecHeader(doc);
237 secHeader.insertSecurityHeader();
238
239 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
240
241 Document unsignedDoc = wsSign.build(samlAssertion);
242
243 if (LOG.isDebugEnabled()) {
244 String outputString =
245 XMLUtils.prettyDocumentToString(unsignedDoc);
246 LOG.debug(outputString);
247 }
248
249 WSHandlerResult results =
250 verify(unsignedDoc, new DummyValidator(), WSConstants.SAML_TOKEN, null);
251
252 List<WSSecurityEngineResult> samlResults =
253 results.getActionResults().get(WSConstants.ST_UNSIGNED);
254 WSSecurityEngineResult actionResult = samlResults.get(0);
255
256 SamlAssertionWrapper receivedSamlAssertion =
257 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
258 assertNotNull(receivedSamlAssertion);
259
260 Principal principal = (Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
261 assertTrue(principal instanceof SAMLTokenPrincipal);
262 assertTrue(principal.getName().contains("uid=joe"));
263 assertNotNull(((SAMLTokenPrincipal)principal).getToken());
264 }
265
266
267
268
269
270 @Test
271 public void testBinarySecurityToken() throws Exception {
272 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
273
274 WSSecHeader secHeader = new WSSecHeader(doc);
275 secHeader.insertSecurityHeader();
276
277 X509Security bst = new X509Security(doc);
278 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
279 cryptoType.setAlias("wss40");
280 Crypto crypto = CryptoFactory.getInstance("wss40.properties");
281 X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
282 bst.setX509Certificate(certs[0]);
283
284 WSSecurityUtil.prependChildElement(secHeader.getSecurityHeaderElement(), bst.getElement());
285
286 if (LOG.isDebugEnabled()) {
287 String outputString =
288 XMLUtils.prettyDocumentToString(doc);
289 LOG.debug(outputString);
290 }
291
292 WSHandlerResult results =
293 verify(doc, new DummyValidator(), WSConstants.BINARY_TOKEN, crypto);
294
295 List<WSSecurityEngineResult> bstResults =
296 results.getActionResults().get(WSConstants.BST);
297 WSSecurityEngineResult actionResult = bstResults.get(0);
298
299 BinarySecurity token =
300 (BinarySecurity)actionResult.get(WSSecurityEngineResult.TAG_BINARY_SECURITY_TOKEN);
301 assertNotNull(token);
302
303 Principal principal = (Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
304 assertTrue(principal instanceof SAMLTokenPrincipal);
305 assertTrue(principal.getName().contains("uid=joe"));
306 assertNotNull(((SAMLTokenPrincipal)principal).getToken());
307 }
308
309
310
311
312 private WSHandlerResult verify(
313 Document doc,
314 Crypto crypto
315 ) throws Exception {
316 return verify(doc, null, null, crypto);
317 }
318
319
320
321
322 private WSHandlerResult verify(
323 Document doc,
324 Validator validator,
325 QName validatorName,
326 Crypto crypto
327 ) throws Exception {
328 RequestData requestData = new RequestData();
329 requestData.setCallbackHandler(callbackHandler);
330 requestData.setDecCrypto(crypto);
331 requestData.setSigVerCrypto(crypto);
332 requestData.setValidateSamlSubjectConfirmation(false);
333
334 WSSecurityEngine secEngine = new WSSecurityEngine();
335 WSSConfig config = WSSConfig.getNewInstance();
336 secEngine.setWssConfig(config);
337
338 if (validator != null && validatorName != null) {
339 config.setValidator(validatorName, validator);
340 }
341 return secEngine.processSecurityHeader(doc, requestData);
342 }
343
344
345
346
347
348 private static class DummyValidator implements Validator {
349
350 public Credential validate(Credential credential, RequestData data) throws WSSecurityException {
351 try {
352 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
353 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
354 callbackHandler.setIssuer("www.example.com");
355
356 SAMLCallback samlCallback = new SAMLCallback();
357 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
358 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
359
360 credential.setTransformedToken(samlAssertion);
361 return credential;
362 } catch (Exception ex) {
363 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE);
364 }
365 }
366
367 }
368 }