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.saml;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.InputStream;
24 import java.security.Key;
25 import java.security.Principal;
26 import java.security.cert.X509Certificate;
27 import java.time.Duration;
28 import java.time.Instant;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.List;
32
33 import javax.crypto.KeyGenerator;
34 import javax.crypto.SecretKey;
35 import javax.security.auth.callback.CallbackHandler;
36 import javax.xml.parsers.DocumentBuilderFactory;
37
38 import org.apache.wss4j.common.bsp.BSPRule;
39 import org.apache.wss4j.common.crypto.Crypto;
40 import org.apache.wss4j.common.crypto.CryptoFactory;
41 import org.apache.wss4j.common.crypto.CryptoType;
42 import org.apache.wss4j.common.ext.WSSecurityException;
43 import org.apache.wss4j.common.saml.SAMLCallback;
44 import org.apache.wss4j.common.saml.SAMLUtil;
45 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
46 import org.apache.wss4j.common.saml.bean.NameIDBean;
47 import org.apache.wss4j.common.saml.bean.SubjectConfirmationDataBean;
48 import org.apache.wss4j.common.saml.builder.SAML1Constants;
49 import org.apache.wss4j.common.saml.builder.SAML2Constants;
50 import org.apache.wss4j.common.token.SecurityTokenReference;
51 import org.apache.wss4j.common.util.DOM2Writer;
52 import org.apache.wss4j.common.util.SOAPUtil;
53 import org.apache.wss4j.common.util.XMLUtils;
54 import org.apache.wss4j.dom.WSConstants;
55 import org.apache.wss4j.dom.common.CustomHandler;
56 import org.apache.wss4j.dom.common.CustomSamlAssertionValidator;
57 import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
58 import org.apache.wss4j.dom.common.SAML1CallbackHandler;
59 import org.apache.wss4j.dom.common.SAML2CallbackHandler;
60 import org.apache.wss4j.dom.common.SAMLElementCallbackHandler;
61
62 import org.apache.wss4j.dom.engine.WSSConfig;
63 import org.apache.wss4j.dom.engine.WSSecurityEngine;
64 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
65 import org.apache.wss4j.dom.handler.HandlerAction;
66 import org.apache.wss4j.dom.handler.RequestData;
67 import org.apache.wss4j.dom.handler.WSHandlerConstants;
68 import org.apache.wss4j.dom.handler.WSHandlerResult;
69 import org.apache.wss4j.dom.message.WSSecHeader;
70 import org.apache.wss4j.dom.message.WSSecSAMLToken;
71 import org.apache.wss4j.dom.validate.SamlAssertionValidator;
72 import org.apache.xml.security.encryption.EncryptedData;
73 import org.apache.xml.security.encryption.EncryptedKey;
74 import org.apache.xml.security.encryption.Reference;
75 import org.apache.xml.security.encryption.ReferenceList;
76 import org.apache.xml.security.encryption.XMLCipher;
77 import org.apache.xml.security.keys.KeyInfo;
78 import org.apache.xml.security.keys.content.RetrievalMethod;
79 import org.apache.xml.security.keys.content.X509Data;
80 import org.apache.xml.security.stax.impl.util.IDGenerator;
81
82 import org.junit.jupiter.api.Test;
83 import org.opensaml.core.xml.XMLObjectBuilder;
84 import org.opensaml.core.xml.XMLObjectBuilderFactory;
85 import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
86 import org.opensaml.core.xml.schema.XSAny;
87 import org.opensaml.core.xml.schema.XSInteger;
88 import org.opensaml.saml.common.SAMLObjectBuilder;
89 import org.opensaml.saml.saml2.core.AttributeValue;
90 import org.opensaml.saml.saml2.core.Conditions;
91 import org.w3c.dom.Document;
92 import org.w3c.dom.Element;
93
94 import static org.junit.jupiter.api.Assertions.assertEquals;
95 import static org.junit.jupiter.api.Assertions.assertFalse;
96 import static org.junit.jupiter.api.Assertions.assertNotNull;
97 import static org.junit.jupiter.api.Assertions.assertNull;
98 import static org.junit.jupiter.api.Assertions.assertTrue;
99 import static org.junit.jupiter.api.Assertions.fail;
100
101
102
103
104 public class SamlTokenTest {
105 private static final org.slf4j.Logger LOG =
106 org.slf4j.LoggerFactory.getLogger(SamlTokenTest.class);
107 private WSSecurityEngine secEngine = new WSSecurityEngine();
108 private static final String IP_ADDRESS = "12.34.56.78";
109
110 public SamlTokenTest() {
111 WSSConfig config = WSSConfig.getNewInstance();
112 config.setValidator(WSConstants.SAML_TOKEN, new CustomSamlAssertionValidator());
113 config.setValidator(WSConstants.SAML2_TOKEN, new CustomSamlAssertionValidator());
114 secEngine.setWssConfig(config);
115 }
116
117
118
119
120 @Test
121 public void testSAML1AuthnAssertion() throws Exception {
122 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
123 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
124 callbackHandler.setIssuer("www.example.com");
125
126 WSHandlerResult results =
127 createAndVerifyMessage(callbackHandler, true);
128 WSSecurityEngineResult actionResult =
129 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
130
131 SamlAssertionWrapper receivedSamlAssertion =
132 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
133 assertNotNull(receivedSamlAssertion);
134 assertFalse(receivedSamlAssertion.isSigned());
135 assertTrue(receivedSamlAssertion.getSignatureValue().length == 0);
136 }
137
138
139
140
141
142
143 @Test
144 public void testSAML1AuthnAssertionViaElement() throws Exception {
145 SAMLElementCallbackHandler callbackHandler = new SAMLElementCallbackHandler();
146 callbackHandler.setIssuer("www.example.com");
147
148 WSHandlerResult results =
149 createAndVerifyMessage(callbackHandler, true);
150 WSSecurityEngineResult actionResult =
151 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
152
153 SamlAssertionWrapper receivedSamlAssertion =
154 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
155 assertNotNull(receivedSamlAssertion);
156 assertFalse(receivedSamlAssertion.isSigned());
157 assertTrue(receivedSamlAssertion.getSignatureValue().length == 0);
158 }
159
160
161
162
163 @Test
164 public void testSAML1AttrAssertion() throws Exception {
165 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
166 callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
167 callbackHandler.setIssuer("www.example.com");
168
169 WSHandlerResult results =
170 createAndVerifyMessage(callbackHandler, true);
171 WSSecurityEngineResult actionResult =
172 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
173
174 SamlAssertionWrapper receivedSamlAssertion =
175 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
176 assertNotNull(receivedSamlAssertion);
177 assertFalse(receivedSamlAssertion.isSigned());
178 }
179
180
181
182
183 @Test
184 public void testSAML1AuthzAssertion() throws Exception {
185 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
186 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHZ);
187 callbackHandler.setIssuer("www.example.com");
188 callbackHandler.setResource("http://resource.org");
189
190 WSHandlerResult results =
191 createAndVerifyMessage(callbackHandler, true);
192 WSSecurityEngineResult actionResult =
193 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
194
195 SamlAssertionWrapper receivedSamlAssertion =
196 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
197 assertNotNull(receivedSamlAssertion);
198 assertFalse(receivedSamlAssertion.isSigned());
199 }
200
201
202
203
204 @Test
205 public void testSAML2AuthnAssertion() throws Exception {
206 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
207 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
208 callbackHandler.setIssuer("www.example.com");
209
210 WSHandlerResult results =
211 createAndVerifyMessage(callbackHandler, true);
212 WSSecurityEngineResult actionResult =
213 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
214
215 SamlAssertionWrapper receivedSamlAssertion =
216 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
217 assertNotNull(receivedSamlAssertion);
218 assertFalse(receivedSamlAssertion.isSigned());
219 }
220
221
222
223
224 @Test
225 public void testSAML2AttrAssertion() throws Exception {
226 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
227 callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
228 callbackHandler.setIssuer("www.example.com");
229
230 WSHandlerResult results =
231 createAndVerifyMessage(callbackHandler, true);
232 WSSecurityEngineResult actionResult =
233 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
234
235 SamlAssertionWrapper receivedSamlAssertion =
236 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
237 assertNotNull(receivedSamlAssertion);
238 assertFalse(receivedSamlAssertion.isSigned());
239 }
240
241
242
243
244 @Test
245 public void testSAML2AuthzAssertion() throws Exception {
246 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
247 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHZ);
248 callbackHandler.setIssuer("www.example.com");
249 callbackHandler.setResource("http://resource.org");
250
251 WSHandlerResult results =
252 createAndVerifyMessage(callbackHandler, true);
253 WSSecurityEngineResult actionResult =
254 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
255
256 SamlAssertionWrapper receivedSamlAssertion =
257 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
258 assertNotNull(receivedSamlAssertion);
259 assertFalse(receivedSamlAssertion.isSigned());
260 }
261
262
263
264
265
266 @Test
267 public void testSaml1Action() throws Exception {
268 final WSSConfig cfg = WSSConfig.getNewInstance();
269 final RequestData reqData = new RequestData();
270 reqData.setWssConfig(cfg);
271 java.util.Map<String, Object> config = new java.util.TreeMap<>();
272 config.put(WSHandlerConstants.SAML_CALLBACK_REF, new SAML1CallbackHandler());
273 reqData.setMsgContext(config);
274
275 final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
276 CustomHandler handler = new CustomHandler();
277 HandlerAction action = new HandlerAction(WSConstants.ST_UNSIGNED);
278 handler.send(
279 doc,
280 reqData,
281 Collections.singletonList(action),
282 true
283 );
284 String outputString =
285 XMLUtils.prettyDocumentToString(doc);
286 if (LOG.isDebugEnabled()) {
287 LOG.debug("Unsigned SAML 1.1 authentication assertion via an Action:");
288 LOG.debug(outputString);
289 }
290 assertFalse(outputString.contains("Signature"));
291
292 WSHandlerResult results = verify(doc);
293 WSSecurityEngineResult actionResult =
294 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
295
296 SamlAssertionWrapper receivedSamlAssertion =
297 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
298 assertNotNull(receivedSamlAssertion);
299 assertFalse(receivedSamlAssertion.isSigned());
300 }
301
302
303
304
305
306
307 @Test
308 public void testSAML1AuthnBadIssuerAssertion() throws Exception {
309 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
310 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
311 callbackHandler.setIssuer("www.example2.com");
312
313 createAndVerifyMessage(callbackHandler, false);
314 }
315
316
317
318
319
320
321 @Test
322 public void testSAML2AuthnBadIssuerAssertion() throws Exception {
323 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
324 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
325 callbackHandler.setIssuer("www.example2.com");
326
327 createAndVerifyMessage(callbackHandler, false);
328 }
329
330
331
332
333
334 @Test
335 public void testSAML1SubjectNameIDFormat() throws Exception {
336 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
337 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
338 callbackHandler.setIssuer("www.example.com");
339 callbackHandler.setSubjectNameIDFormat(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS);
340
341 SAMLCallback samlCallback = new SAMLCallback();
342 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
343 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
344
345 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
346 WSSecHeader secHeader = new WSSecHeader(doc);
347 secHeader.insertSecurityHeader();
348
349 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
350
351 Document unsignedDoc = wsSign.build(samlAssertion);
352
353 String outputString =
354 XMLUtils.prettyDocumentToString(unsignedDoc);
355 if (LOG.isDebugEnabled()) {
356 LOG.debug("SAML 1.1 Authn Assertion (sender vouches):");
357 LOG.debug(outputString);
358 }
359 assertTrue(outputString.contains(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS));
360
361 WSHandlerResult results = verify(unsignedDoc);
362 WSSecurityEngineResult actionResult =
363 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
364
365 SamlAssertionWrapper receivedSamlAssertion =
366 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
367 assertNotNull(receivedSamlAssertion);
368 assertFalse(receivedSamlAssertion.isSigned());
369 }
370
371
372
373
374
375 @Test
376 public void testSAML2SubjectNameIDFormat() throws Exception {
377 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
378 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
379 callbackHandler.setIssuer("www.example.com");
380 callbackHandler.setSubjectNameIDFormat(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS);
381
382 SAMLCallback samlCallback = new SAMLCallback();
383 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
384 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
385
386 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
387 WSSecHeader secHeader = new WSSecHeader(doc);
388 secHeader.insertSecurityHeader();
389
390 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
391
392 Document unsignedDoc = wsSign.build(samlAssertion);
393
394 String outputString =
395 XMLUtils.prettyDocumentToString(unsignedDoc);
396 if (LOG.isDebugEnabled()) {
397 LOG.debug("SAML 2 Authn Assertion (sender vouches):");
398 LOG.debug(outputString);
399 }
400 assertTrue(outputString.contains(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS));
401
402 WSHandlerResult results = verify(unsignedDoc);
403 WSSecurityEngineResult actionResult =
404 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
405
406 SamlAssertionWrapper receivedSamlAssertion =
407 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
408 assertNotNull(receivedSamlAssertion);
409 assertFalse(receivedSamlAssertion.isSigned());
410 }
411
412
413
414
415
416 @Test
417 public void testSAML1SubjectLocality() throws Exception {
418 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
419 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
420 callbackHandler.setIssuer("www.example.com");
421 callbackHandler.setSubjectLocality(IP_ADDRESS, "test-dns");
422
423 SAMLCallback samlCallback = new SAMLCallback();
424 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
425 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
426
427 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
428 WSSecHeader secHeader = new WSSecHeader(doc);
429 secHeader.insertSecurityHeader();
430
431 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
432
433 Document unsignedDoc = wsSign.build(samlAssertion);
434
435 String outputString =
436 XMLUtils.prettyDocumentToString(unsignedDoc);
437 if (LOG.isDebugEnabled()) {
438 LOG.debug("SAML 1.1 Authn Assertion (sender vouches):");
439 LOG.debug(outputString);
440 }
441 assertTrue(outputString.contains(IP_ADDRESS));
442 assertTrue(outputString.contains("test-dns"));
443
444 WSHandlerResult results = verify(unsignedDoc);
445 WSSecurityEngineResult actionResult =
446 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
447
448 SamlAssertionWrapper receivedSamlAssertion =
449 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
450 assertNotNull(receivedSamlAssertion);
451 assertFalse(receivedSamlAssertion.isSigned());
452 }
453
454
455
456
457
458 @Test
459 public void testSAML2SessionNotOnOrAfter() throws Exception {
460 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
461 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
462 callbackHandler.setSessionNotOnOrAfter(Instant.now().plus(Duration.ofHours(1)));
463 callbackHandler.setIssuer("www.example.com");
464
465 SAMLCallback samlCallback = new SAMLCallback();
466 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
467 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
468
469 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
470 WSSecHeader secHeader = new WSSecHeader(doc);
471 secHeader.insertSecurityHeader();
472
473 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
474
475 Document unsignedDoc = wsSign.build(samlAssertion);
476
477 String outputString =
478 XMLUtils.prettyDocumentToString(unsignedDoc);
479 if (LOG.isDebugEnabled()) {
480 LOG.debug("SAML 2.0 Authn Assertion (sender vouches):");
481 LOG.debug(outputString);
482 }
483 assertTrue(outputString.contains("SessionNotOnOrAfter"));
484
485 WSHandlerResult results = verify(unsignedDoc);
486 WSSecurityEngineResult actionResult =
487 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
488
489 SamlAssertionWrapper receivedSamlAssertion =
490 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
491 assertNotNull(receivedSamlAssertion);
492 assertFalse(receivedSamlAssertion.isSigned());
493 }
494
495
496
497
498
499 @Test
500 public void testSAML2SubjectLocality() throws Exception {
501 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
502 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
503 callbackHandler.setIssuer("www.example.com");
504 callbackHandler.setSubjectLocality(IP_ADDRESS, "test-dns");
505
506 SAMLCallback samlCallback = new SAMLCallback();
507 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
508 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
509
510 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
511 WSSecHeader secHeader = new WSSecHeader(doc);
512 secHeader.insertSecurityHeader();
513
514 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
515
516 Document unsignedDoc = wsSign.build(samlAssertion);
517
518 String outputString =
519 XMLUtils.prettyDocumentToString(unsignedDoc);
520 if (LOG.isDebugEnabled()) {
521 LOG.debug("SAML 2 Authn Assertion (sender vouches):");
522 LOG.debug(outputString);
523 }
524 assertTrue(outputString.contains(IP_ADDRESS));
525 assertTrue(outputString.contains("test-dns"));
526
527 WSHandlerResult results = verify(unsignedDoc);
528 WSSecurityEngineResult actionResult =
529 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
530
531 SamlAssertionWrapper receivedSamlAssertion =
532 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
533 assertNotNull(receivedSamlAssertion);
534 assertFalse(receivedSamlAssertion.isSigned());
535 }
536
537
538
539
540
541 @Test
542 public void testSAML1Resource() throws Exception {
543 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
544 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHZ);
545 callbackHandler.setIssuer("www.example.com");
546 callbackHandler.setResource("http://resource.org");
547
548 SAMLCallback samlCallback = new SAMLCallback();
549 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
550 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
551
552 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
553 WSSecHeader secHeader = new WSSecHeader(doc);
554 secHeader.insertSecurityHeader();
555
556 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
557
558 Document unsignedDoc = wsSign.build(samlAssertion);
559
560 String outputString =
561 XMLUtils.prettyDocumentToString(unsignedDoc);
562 if (LOG.isDebugEnabled()) {
563 LOG.debug("SAML 1.1 Authz Assertion (sender vouches):");
564 LOG.debug(outputString);
565 }
566 assertTrue(outputString.contains("http://resource.org"));
567
568 WSHandlerResult results = verify(unsignedDoc);
569 WSSecurityEngineResult actionResult =
570 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
571
572 SamlAssertionWrapper receivedSamlAssertion =
573 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
574 assertNotNull(receivedSamlAssertion);
575 assertFalse(receivedSamlAssertion.isSigned());
576 }
577
578
579
580
581
582 @Test
583 @SuppressWarnings("unchecked")
584 public void testSAML2AttrAssertionCustomAttribute() throws Exception {
585 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
586 callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
587 callbackHandler.setIssuer("www.example.com");
588
589
590 XMLObjectBuilderFactory builderFactory =
591 XMLObjectProviderRegistrySupport.getBuilderFactory();
592
593 SAMLObjectBuilder<Conditions> conditionsV2Builder =
594 (SAMLObjectBuilder<Conditions>)builderFactory.getBuilder(Conditions.DEFAULT_ELEMENT_NAME);
595 Conditions conditions = conditionsV2Builder.buildObject();
596 Instant newNotBefore = Instant.now();
597 conditions.setNotBefore(newNotBefore);
598 conditions.setNotOnOrAfter(newNotBefore.plus(Duration.ofMinutes(5)));
599
600 XMLObjectBuilder<XSAny> xsAnyBuilder =
601 (XMLObjectBuilder<XSAny>)builderFactory.getBuilder(XSAny.TYPE_NAME);
602 XSAny attributeValue = xsAnyBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME);
603 attributeValue.getUnknownXMLObjects().add(conditions);
604
605 List<Object> attributeValues = new ArrayList<>();
606 attributeValues.add(attributeValue);
607 callbackHandler.setCustomAttributeValues(attributeValues);
608
609 SAMLCallback samlCallback = new SAMLCallback();
610 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
611 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
612
613 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
614 WSSecHeader secHeader = new WSSecHeader(doc);
615 secHeader.insertSecurityHeader();
616
617 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
618
619 Document unsignedDoc = wsSign.build(samlAssertion);
620
621 if (LOG.isDebugEnabled()) {
622 LOG.debug("SAML 2 Attr Assertion (sender vouches):");
623 String outputString =
624 XMLUtils.prettyDocumentToString(unsignedDoc);
625 LOG.debug(outputString);
626 }
627
628 WSHandlerResult results = verify(unsignedDoc);
629 WSSecurityEngineResult actionResult =
630 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
631
632 SamlAssertionWrapper receivedSamlAssertion =
633 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
634 assertNotNull(receivedSamlAssertion);
635 assertFalse(receivedSamlAssertion.isSigned());
636 }
637
638
639
640
641
642 @Test
643 @SuppressWarnings("unchecked")
644 public void testSAML2AttrAssertionIntegerAttribute() throws Exception {
645 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
646 callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
647 callbackHandler.setIssuer("www.example.com");
648
649
650 XMLObjectBuilderFactory builderFactory = XMLObjectProviderRegistrySupport.getBuilderFactory();
651
652 XMLObjectBuilder<XSInteger> xsIntegerBuilder =
653 (XMLObjectBuilder<XSInteger>)builderFactory.getBuilder(XSInteger.TYPE_NAME);
654 XSInteger attributeValue =
655 xsIntegerBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSInteger.TYPE_NAME);
656 attributeValue.setValue(5);
657
658 List<Object> attributeValues = new ArrayList<>();
659 attributeValues.add(attributeValue);
660 callbackHandler.setCustomAttributeValues(attributeValues);
661
662 WSHandlerResult results = createAndVerifyMessage(callbackHandler, true);
663 WSSecurityEngineResult actionResult =
664 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
665
666 SamlAssertionWrapper receivedSamlAssertion =
667 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
668 assertNotNull(receivedSamlAssertion);
669 assertFalse(receivedSamlAssertion.isSigned());
670 }
671
672
673
674
675
676 @Test
677 public void testSAML2SubjectConfirmationData() throws Exception {
678 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
679 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
680 callbackHandler.setIssuer("www.example.com");
681
682 SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
683 subjectConfirmationData.setAddress("http://apache.org");
684 subjectConfirmationData.setInResponseTo("12345");
685 subjectConfirmationData.setNotAfter(Instant.now().plus(Duration.ofMinutes(5)));
686 subjectConfirmationData.setRecipient("http://recipient.apache.org");
687 callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
688
689 SAMLCallback samlCallback = new SAMLCallback();
690 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
691 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
692
693 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
694 WSSecHeader secHeader = new WSSecHeader(doc);
695 secHeader.insertSecurityHeader();
696
697 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
698
699 Document unsignedDoc = wsSign.build(samlAssertion);
700
701 String outputString =
702 XMLUtils.prettyDocumentToString(unsignedDoc);
703 if (LOG.isDebugEnabled()) {
704 LOG.debug("SAML 2 Authn Assertion (sender vouches):");
705 LOG.debug(outputString);
706 }
707 assertTrue(outputString.contains("http://recipient.apache.org"));
708
709 WSHandlerResult results = createAndVerifyMessage(callbackHandler, true);
710 WSSecurityEngineResult actionResult =
711 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
712
713 SamlAssertionWrapper receivedSamlAssertion =
714 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
715 assertNotNull(receivedSamlAssertion);
716 assertFalse(receivedSamlAssertion.isSigned());
717 }
718
719
720
721
722
723 @Test
724 public void testSAML2SubjectConfirmationNameID() throws Exception {
725 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
726 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
727 callbackHandler.setIssuer("www.example.com");
728
729 NameIDBean nameID = new NameIDBean();
730 nameID.setNameIDFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified");
731 nameID.setNameQualifier("confirmationNameQualifier");
732 nameID.setNameValue("confirmationNameQualifierValue");
733 nameID.setSPNameQualifier("spNameQualifier");
734 callbackHandler.setSubjectConfirmationNameID(nameID);
735
736 SAMLCallback samlCallback = new SAMLCallback();
737 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
738 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
739
740 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
741 WSSecHeader secHeader = new WSSecHeader(doc);
742 secHeader.insertSecurityHeader();
743
744 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
745
746 Document unsignedDoc = wsSign.build(samlAssertion);
747
748 String outputString =
749 XMLUtils.prettyDocumentToString(unsignedDoc);
750 if (LOG.isDebugEnabled()) {
751 LOG.debug("SAML 2 Authn Assertion (sender vouches):");
752 LOG.debug(outputString);
753 }
754 assertTrue(outputString.contains("confirmationNameQualifierValue"));
755
756 WSHandlerResult results = createAndVerifyMessage(callbackHandler, true);
757 WSSecurityEngineResult actionResult =
758 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
759
760 SamlAssertionWrapper receivedSamlAssertion =
761 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
762 assertNotNull(receivedSamlAssertion);
763 assertFalse(receivedSamlAssertion.isSigned());
764 }
765
766
767
768
769
770 @Test
771 public void testSAML2EncryptedAssertion() throws Exception {
772 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
773 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
774 callbackHandler.setIssuer("www.example.com");
775
776 SAMLCallback samlCallback = new SAMLCallback();
777 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
778 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
779
780 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
781 WSSecHeader secHeader = new WSSecHeader(doc);
782 secHeader.insertSecurityHeader();
783
784 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
785
786 wsSign.prepare(samlAssertion);
787
788
789 Element assertionElement = wsSign.getElement();
790 Element encryptedAssertionElement =
791 doc.createElementNS(WSConstants.SAML2_NS, WSConstants.ENCRYPED_ASSERTION_LN);
792 encryptedAssertionElement.appendChild(assertionElement);
793 secHeader.getSecurityHeaderElement().appendChild(encryptedAssertionElement);
794
795
796 KeyGenerator keygen = KeyGenerator.getInstance("AES");
797 keygen.init(128);
798 SecretKey secretKey = keygen.generateKey();
799 Crypto crypto = CryptoFactory.getInstance("wss40.properties");
800 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
801 cryptoType.setAlias("wss40");
802 X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
803 assertTrue(certs != null && certs.length > 0 && certs[0] != null);
804
805 encryptElement(doc, assertionElement, WSConstants.AES_128, secretKey,
806 WSConstants.KEYTRANSPORT_RSAOAEP, certs[0], false, true);
807
808 if (LOG.isDebugEnabled()) {
809 String outputString =
810 XMLUtils.prettyDocumentToString(doc);
811 LOG.debug(outputString);
812 }
813
814 RequestData requestData = new RequestData();
815 requestData.setValidateSamlSubjectConfirmation(false);
816 requestData.setCallbackHandler(new KeystoreCallbackHandler());
817 requestData.setDecCrypto(crypto);
818 requestData.setSigVerCrypto(crypto);
819 WSHandlerResult results = secEngine.processSecurityHeader(doc, requestData);
820
821 WSSecurityEngineResult actionResult =
822 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
823
824 SamlAssertionWrapper receivedSamlAssertion =
825 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
826 assertNotNull(receivedSamlAssertion);
827 assertNotNull(receivedSamlAssertion.getElement());
828 assertTrue("Assertion".equals(receivedSamlAssertion.getElement().getLocalName()));
829
830 actionResult = results.getActionResults().get(WSConstants.ENCR).get(0);
831 assertNotNull(actionResult);
832 }
833
834 @Test
835 public void testSAML2EncryptedAssertionViaSeparateEncryptedKey() throws Exception {
836 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
837 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
838 callbackHandler.setIssuer("www.example.com");
839
840 SAMLCallback samlCallback = new SAMLCallback();
841 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
842 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
843
844 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
845 WSSecHeader secHeader = new WSSecHeader(doc);
846 secHeader.insertSecurityHeader();
847
848 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
849
850 wsSign.prepare(samlAssertion);
851
852
853 Element assertionElement = wsSign.getElement();
854 Element encryptedAssertionElement =
855 doc.createElementNS(WSConstants.SAML2_NS, WSConstants.ENCRYPED_ASSERTION_LN);
856 encryptedAssertionElement.appendChild(assertionElement);
857 secHeader.getSecurityHeaderElement().appendChild(encryptedAssertionElement);
858
859
860 KeyGenerator keygen = KeyGenerator.getInstance("AES");
861 keygen.init(128);
862 SecretKey secretKey = keygen.generateKey();
863 Crypto crypto = CryptoFactory.getInstance("wss40.properties");
864 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
865 cryptoType.setAlias("wss40");
866 X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
867 assertTrue(certs != null && certs.length > 0 && certs[0] != null);
868
869 XMLCipher cipher = XMLCipher.getInstance(WSConstants.AES_128);
870 cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
871
872
873 EncryptedData builder = cipher.getEncryptedData();
874 KeyInfo builderKeyInfo = builder.getKeyInfo();
875 if (builderKeyInfo == null) {
876 builderKeyInfo = new KeyInfo(doc);
877 builderKeyInfo.getElement().setAttributeNS(
878 "http://www.w3.org/2000/xmlns/", "xmlns:dsig",
879 "http://www.w3.org/2000/09/xmldsig#"
880 );
881 builder.setKeyInfo(builderKeyInfo);
882 }
883 String encryptedKeyId = IDGenerator.generateID(null);
884 RetrievalMethod retrievalMethod = new RetrievalMethod(doc, "#" + encryptedKeyId,
885 null, "http://www.w3.org/2001/04/xmlenc#EncryptedKey");
886 builderKeyInfo.add(retrievalMethod);
887
888 cipher.doFinal(doc, assertionElement, false);
889
890 String id = IDGenerator.generateID(null);
891 Element encryptedData =
892 (Element)encryptedAssertionElement.getElementsByTagNameNS(WSConstants.ENC_NS, "EncryptedData").item(0);
893 encryptedData.setAttributeNS(null, "Id", id);
894
895 XMLCipher newCipher = XMLCipher.getInstance(WSConstants.KEYTRANSPORT_RSAOAEP);
896 newCipher.init(XMLCipher.WRAP_MODE, certs[0].getPublicKey());
897 EncryptedKey encryptedKey = newCipher.encryptKey(doc, secretKey);
898
899 KeyInfo encryptedKeyKeyInfo = encryptedKey.getKeyInfo();
900 if (encryptedKeyKeyInfo == null) {
901 encryptedKeyKeyInfo = new KeyInfo(doc);
902 encryptedKeyKeyInfo.getElement().setAttributeNS(
903 "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
904 );
905 encryptedKey.setKeyInfo(encryptedKeyKeyInfo);
906 }
907 X509Data x509Data = new X509Data(doc);
908 x509Data.addIssuerSerial(certs[0].getIssuerX500Principal().getName(),
909 certs[0].getSerialNumber());
910 encryptedKeyKeyInfo.add(x509Data);
911
912 ReferenceList referenceList = newCipher.createReferenceList(ReferenceList.DATA_REFERENCE);
913 Reference reference = referenceList.newDataReference("#" + id);
914 referenceList.add(reference);
915 encryptedKey.setReferenceList(referenceList);
916 Element encryptedKeyElement = newCipher.martial(encryptedKey);
917 encryptedKeyElement.setAttributeNS(null, "Id", encryptedKeyId);
918 encryptedAssertionElement.appendChild(encryptedKeyElement);
919
920 if (LOG.isDebugEnabled()) {
921 String outputString =
922 XMLUtils.prettyDocumentToString(doc);
923 LOG.debug(outputString);
924 }
925
926 RequestData requestData = new RequestData();
927 requestData.setValidateSamlSubjectConfirmation(false);
928 requestData.setCallbackHandler(new KeystoreCallbackHandler());
929 requestData.setDecCrypto(crypto);
930 requestData.setSigVerCrypto(crypto);
931 requestData.setDisableBSPEnforcement(true);
932 WSHandlerResult results = secEngine.processSecurityHeader(doc, requestData);
933
934 WSSecurityEngineResult actionResult =
935 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
936
937 SamlAssertionWrapper receivedSamlAssertion =
938 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
939 assertNotNull(receivedSamlAssertion);
940 assertNotNull(receivedSamlAssertion.getElement());
941 assertTrue("Assertion".equals(receivedSamlAssertion.getElement().getLocalName()));
942
943 actionResult = results.getActionResults().get(WSConstants.ENCR).get(0);
944 assertNotNull(actionResult);
945 }
946
947 @Test
948 public void testSAML2EncryptedAssertionNoSTR() throws Exception {
949 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
950 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
951 callbackHandler.setIssuer("www.example.com");
952
953 SAMLCallback samlCallback = new SAMLCallback();
954 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
955 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
956
957 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
958 WSSecHeader secHeader = new WSSecHeader(doc);
959 secHeader.insertSecurityHeader();
960
961 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
962
963 wsSign.prepare(samlAssertion);
964
965
966 Element assertionElement = wsSign.getElement();
967 Element encryptedAssertionElement =
968 doc.createElementNS(WSConstants.SAML2_NS, WSConstants.ENCRYPED_ASSERTION_LN);
969 encryptedAssertionElement.appendChild(assertionElement);
970 secHeader.getSecurityHeaderElement().appendChild(encryptedAssertionElement);
971
972
973 KeyGenerator keygen = KeyGenerator.getInstance("AES");
974 keygen.init(128);
975 SecretKey secretKey = keygen.generateKey();
976 Crypto crypto = CryptoFactory.getInstance("wss40.properties");
977 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
978 cryptoType.setAlias("wss40");
979 X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
980 assertTrue(certs != null && certs.length > 0 && certs[0] != null);
981
982 encryptElement(doc, assertionElement, WSConstants.AES_128, secretKey,
983 WSConstants.KEYTRANSPORT_RSAOAEP, certs[0], false, false);
984
985 if (LOG.isDebugEnabled()) {
986 String outputString =
987 XMLUtils.prettyDocumentToString(doc);
988 LOG.debug(outputString);
989 }
990
991 RequestData data = new RequestData();
992 data.setDecCrypto(crypto);
993 List<BSPRule> ignoredRules = new ArrayList<>();
994 ignoredRules.add(BSPRule.R5426);
995 data.setIgnoredBSPRules(ignoredRules);
996 data.setCallbackHandler(new KeystoreCallbackHandler());
997 data.setValidateSamlSubjectConfirmation(false);
998
999 WSSecurityEngine newEngine = new WSSecurityEngine();
1000
1001 WSSConfig config = WSSConfig.getNewInstance();
1002 config.setValidator(WSConstants.SAML_TOKEN, new CustomSamlAssertionValidator());
1003 config.setValidator(WSConstants.SAML2_TOKEN, new CustomSamlAssertionValidator());
1004 newEngine.setWssConfig(config);
1005
1006 WSHandlerResult results = newEngine.processSecurityHeader(doc, data);
1007
1008 WSSecurityEngineResult actionResult =
1009 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
1010
1011 SamlAssertionWrapper receivedSamlAssertion =
1012 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
1013 assertNotNull(receivedSamlAssertion);
1014 assertNotNull(receivedSamlAssertion.getElement());
1015 assertTrue("Assertion".equals(receivedSamlAssertion.getElement().getLocalName()));
1016
1017 actionResult = results.getActionResults().get(WSConstants.ENCR).get(0);
1018 assertNotNull(actionResult);
1019 }
1020
1021 @Test
1022 public void testAssertionWrapper() throws Exception {
1023 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
1024 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
1025 callbackHandler.setIssuer("www.example.com");
1026
1027 SAMLCallback samlCallback = new SAMLCallback();
1028 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1029 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1030
1031 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1032 dbf.setNamespaceAware(true);
1033 Document doc = dbf.newDocumentBuilder().newDocument();
1034 String assertionString = DOM2Writer.nodeToString(samlAssertion.toDOM(doc));
1035
1036
1037 InputStream in = new ByteArrayInputStream(assertionString.getBytes());
1038 Document newDoc = dbf.newDocumentBuilder().parse(in);
1039
1040 SamlAssertionWrapper newAssertion =
1041 new SamlAssertionWrapper(newDoc.getDocumentElement());
1042 String secondAssertionString = newAssertion.assertionToString();
1043 assertEquals(assertionString, secondAssertionString);
1044 }
1045
1046 @Test
1047 public void testAssertionWrapperNoDocument() throws Exception {
1048 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
1049 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
1050 callbackHandler.setIssuer("www.example.com");
1051
1052 SAMLCallback samlCallback = new SAMLCallback();
1053 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1054 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1055
1056 String assertionString = DOM2Writer.nodeToString(samlAssertion.toDOM(null));
1057
1058
1059 InputStream in = new ByteArrayInputStream(assertionString.getBytes());
1060
1061 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1062 dbf.setNamespaceAware(true);
1063 Document newDoc = dbf.newDocumentBuilder().parse(in);
1064
1065 SamlAssertionWrapper newAssertion =
1066 new SamlAssertionWrapper(newDoc.getDocumentElement());
1067 String secondAssertionString = newAssertion.assertionToString();
1068 assertEquals(assertionString, secondAssertionString);
1069 }
1070
1071 @Test
1072 public void testRequiredSubjectConfirmationMethod() throws Exception {
1073 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1074 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1075 callbackHandler.setIssuer("www.example.com");
1076
1077 SAMLCallback samlCallback = new SAMLCallback();
1078 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1079 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1080
1081 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1082 WSSecHeader secHeader = new WSSecHeader(doc);
1083 secHeader.insertSecurityHeader();
1084
1085 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1086
1087 Document unsignedDoc = wsSign.build(samlAssertion);
1088
1089 WSSConfig config = WSSConfig.getNewInstance();
1090 SamlAssertionValidator assertionValidator = new SamlAssertionValidator();
1091 assertionValidator.setRequiredSubjectConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
1092 config.setValidator(WSConstants.SAML_TOKEN, assertionValidator);
1093 config.setValidator(WSConstants.SAML2_TOKEN, assertionValidator);
1094
1095 WSSecurityEngine newEngine = new WSSecurityEngine();
1096 newEngine.setWssConfig(config);
1097 RequestData requestData = new RequestData();
1098 requestData.setValidateSamlSubjectConfirmation(false);
1099
1100 newEngine.processSecurityHeader(doc, requestData);
1101
1102
1103 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
1104
1105 samlCallback = new SAMLCallback();
1106 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1107 samlAssertion = new SamlAssertionWrapper(samlCallback);
1108
1109 doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1110 secHeader = new WSSecHeader(doc);
1111 secHeader.insertSecurityHeader();
1112
1113 wsSign = new WSSecSAMLToken(secHeader);
1114
1115 unsignedDoc = wsSign.build(samlAssertion);
1116 try {
1117 newEngine.processSecurityHeader(unsignedDoc, null, null, null);
1118 fail("Failure expected on an incorrect subject confirmation method");
1119 } catch (WSSecurityException ex) {
1120 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
1121 }
1122 }
1123
1124 @Test
1125 public void testStandardSubjectConfirmationMethod() throws Exception {
1126 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1127 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1128 callbackHandler.setIssuer("www.example.com");
1129 callbackHandler.setConfirmationMethod("urn:oasis:names:tc:SAML:2.0:cm:custom");
1130
1131 SAMLCallback samlCallback = new SAMLCallback();
1132 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1133 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1134
1135 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1136 WSSecHeader secHeader = new WSSecHeader(doc);
1137 secHeader.insertSecurityHeader();
1138
1139 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1140
1141 Document unsignedDoc = wsSign.build(samlAssertion);
1142
1143 WSSecurityEngine newEngine = new WSSecurityEngine();
1144 try {
1145 newEngine.processSecurityHeader(unsignedDoc, null, null, null);
1146 fail("Failure expected on an unknown subject confirmation method");
1147 } catch (WSSecurityException ex) {
1148 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
1149 }
1150
1151
1152 WSSConfig config = WSSConfig.getNewInstance();
1153 SamlAssertionValidator assertionValidator = new SamlAssertionValidator();
1154 assertionValidator.setRequireStandardSubjectConfirmationMethod(false);
1155 config.setValidator(WSConstants.SAML_TOKEN, assertionValidator);
1156 config.setValidator(WSConstants.SAML2_TOKEN, assertionValidator);
1157
1158 newEngine.setWssConfig(config);
1159
1160 RequestData requestData = new RequestData();
1161 requestData.setValidateSamlSubjectConfirmation(false);
1162
1163 newEngine.processSecurityHeader(doc, requestData);
1164 }
1165
1166 @Test
1167 public void testUnsignedBearer() throws Exception {
1168 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1169 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1170 callbackHandler.setIssuer("www.example.com");
1171 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
1172
1173 SAMLCallback samlCallback = new SAMLCallback();
1174 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1175 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1176
1177 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1178 WSSecHeader secHeader = new WSSecHeader(doc);
1179 secHeader.insertSecurityHeader();
1180
1181 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1182
1183 Document unsignedDoc = wsSign.build(samlAssertion);
1184
1185 WSSecurityEngine newEngine = new WSSecurityEngine();
1186 try {
1187 newEngine.processSecurityHeader(unsignedDoc, null, null, null);
1188 fail("Failure expected on an unsigned bearer token");
1189 } catch (WSSecurityException ex) {
1190 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
1191 }
1192
1193
1194 WSSConfig config = WSSConfig.getNewInstance();
1195 SamlAssertionValidator assertionValidator = new SamlAssertionValidator();
1196 assertionValidator.setRequireBearerSignature(false);
1197 config.setValidator(WSConstants.SAML_TOKEN, assertionValidator);
1198 config.setValidator(WSConstants.SAML2_TOKEN, assertionValidator);
1199
1200 newEngine.setWssConfig(config);
1201
1202 RequestData requestData = new RequestData();
1203 requestData.setValidateSamlSubjectConfirmation(false);
1204
1205 newEngine.processSecurityHeader(doc, requestData);
1206 }
1207
1208 @Test
1209 public void testSAML2Advice() throws Exception {
1210
1211 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1212 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1213 callbackHandler.setIssuer("www.example.com");
1214
1215 SAMLCallback samlCallback = new SAMLCallback();
1216 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1217 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1218
1219 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1220 Element adviceElement = samlAssertion.toDOM(doc);
1221
1222
1223 callbackHandler = new SAML2CallbackHandler();
1224 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1225 callbackHandler.setIssuer("www.example.com");
1226 callbackHandler.setAssertionAdviceElement(adviceElement);
1227
1228 samlCallback = new SAMLCallback();
1229 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1230 samlAssertion = new SamlAssertionWrapper(samlCallback);
1231
1232 WSSecHeader secHeader = new WSSecHeader(doc);
1233 secHeader.insertSecurityHeader();
1234
1235 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1236
1237 Document unsignedDoc = wsSign.build(samlAssertion);
1238
1239 String outputString =
1240 XMLUtils.prettyDocumentToString(unsignedDoc);
1241 if (LOG.isDebugEnabled()) {
1242 LOG.debug(outputString);
1243 }
1244 assertTrue(outputString.contains("Advice"));
1245
1246 WSHandlerResult results = verify(unsignedDoc);
1247 WSSecurityEngineResult actionResult =
1248 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
1249
1250 SamlAssertionWrapper receivedSamlAssertion =
1251 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
1252 assertNotNull(receivedSamlAssertion);
1253 assertFalse(receivedSamlAssertion.isSigned());
1254 }
1255
1256 @Test
1257 public void testSAML2SpecialCharacter() throws Exception {
1258 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1259 callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
1260 callbackHandler.setIssuer("www.example.com");
1261
1262 String newSubjectName = "uid=j\u00f6e,ou=people,ou=saml-demo,o=example.com";
1263 callbackHandler.setSubjectName(newSubjectName);
1264 List<Object> customAttributeValue = new ArrayList<>(1);
1265 customAttributeValue.add("j\u00f6an");
1266 callbackHandler.setCustomAttributeValues(customAttributeValue);
1267
1268 SAMLCallback samlCallback = new SAMLCallback();
1269 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1270 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1271
1272 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1273 WSSecHeader secHeader = new WSSecHeader(doc);
1274 secHeader.insertSecurityHeader();
1275
1276 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1277
1278 Document unsignedDoc = wsSign.build(samlAssertion);
1279
1280 String outputString = XMLUtils.prettyDocumentToString(unsignedDoc);
1281
1282 if (LOG.isDebugEnabled()) {
1283 LOG.debug(outputString);
1284 }
1285
1286 RequestData requestData = new RequestData();
1287 requestData.setValidateSamlSubjectConfirmation(false);
1288
1289 WSSecurityEngine newEngine = new WSSecurityEngine();
1290 WSHandlerResult results = newEngine.processSecurityHeader(doc, requestData);
1291
1292 WSSecurityEngineResult actionResult =
1293 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
1294
1295 SamlAssertionWrapper receivedSamlAssertion =
1296 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
1297 assertNotNull(receivedSamlAssertion);
1298 assertFalse(receivedSamlAssertion.isSigned());
1299 }
1300
1301 @Test
1302 public void testSAML2IssuerFormat() throws Exception {
1303 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1304 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1305 callbackHandler.setIssuer("www.example.com");
1306 callbackHandler.setIssuerFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent");
1307
1308 SAMLCallback samlCallback = new SAMLCallback();
1309 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
1310 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1311
1312 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1313 WSSecHeader secHeader = new WSSecHeader(doc);
1314 secHeader.insertSecurityHeader();
1315
1316 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1317
1318 Document unsignedDoc = wsSign.build(samlAssertion);
1319
1320 String outputString =
1321 XMLUtils.prettyDocumentToString(unsignedDoc);
1322 if (LOG.isDebugEnabled()) {
1323 LOG.debug(outputString);
1324 }
1325 assertTrue(outputString.contains("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"));
1326
1327 WSHandlerResult results = createAndVerifyMessage(callbackHandler, true);
1328 WSSecurityEngineResult actionResult =
1329 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
1330
1331 SamlAssertionWrapper receivedSamlAssertion =
1332 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
1333 assertNotNull(receivedSamlAssertion);
1334 assertFalse(receivedSamlAssertion.isSigned());
1335 }
1336
1337 @Test
1338 public void testSAML2SubjectWithComment() throws Exception {
1339 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1340 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1341 callbackHandler.setIssuer("www.example.com");
1342 String principal = "uid=joe,ou=people<!---->o=example.com";
1343 callbackHandler.setSubjectName(principal);
1344
1345 WSHandlerResult results =
1346 createAndVerifyMessage(callbackHandler, true);
1347 WSSecurityEngineResult actionResult =
1348 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
1349
1350 SamlAssertionWrapper receivedSamlAssertion =
1351 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
1352 assertNotNull(receivedSamlAssertion);
1353 assertFalse(receivedSamlAssertion.isSigned());
1354
1355 Principal receivedPrincipal = (Principal)actionResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
1356 assertEquals(principal, receivedPrincipal.getName());
1357 }
1358
1359 private void encryptElement(
1360 Document document,
1361 Element elementToEncrypt,
1362 String algorithm,
1363 Key encryptingKey,
1364 String keyTransportAlgorithm,
1365 X509Certificate wrappingCert,
1366 boolean content,
1367 boolean useSecurityTokenReference
1368 ) throws Exception {
1369 XMLCipher cipher = XMLCipher.getInstance(algorithm);
1370 cipher.init(XMLCipher.ENCRYPT_MODE, encryptingKey);
1371
1372 if (wrappingCert != null) {
1373 XMLCipher newCipher = XMLCipher.getInstance(keyTransportAlgorithm);
1374 newCipher.init(XMLCipher.WRAP_MODE, wrappingCert.getPublicKey());
1375
1376 EncryptedKey encryptedKey = newCipher.encryptKey(document, encryptingKey);
1377
1378 KeyInfo encryptedKeyKeyInfo = encryptedKey.getKeyInfo();
1379 if (encryptedKeyKeyInfo == null) {
1380 encryptedKeyKeyInfo = new KeyInfo(document);
1381 encryptedKeyKeyInfo.getElement().setAttributeNS(
1382 "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
1383 );
1384 encryptedKey.setKeyInfo(encryptedKeyKeyInfo);
1385 }
1386
1387 if (useSecurityTokenReference) {
1388 SecurityTokenReference securityTokenReference = new SecurityTokenReference(document);
1389 securityTokenReference.addWSSENamespace();
1390 securityTokenReference.setKeyIdentifierSKI(wrappingCert, null);
1391 encryptedKeyKeyInfo.addUnknownElement(securityTokenReference.getElement());
1392 } else {
1393 X509Data x509Data = new X509Data(document);
1394
1395 x509Data.addIssuerSerial(wrappingCert.getIssuerX500Principal().getName(),
1396 wrappingCert.getSerialNumber());
1397 encryptedKeyKeyInfo.add(x509Data);
1398 }
1399
1400
1401 EncryptedData builder = cipher.getEncryptedData();
1402 KeyInfo builderKeyInfo = builder.getKeyInfo();
1403 if (builderKeyInfo == null) {
1404 builderKeyInfo = new KeyInfo(document);
1405 builderKeyInfo.getElement().setAttributeNS(
1406 "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
1407 );
1408 builder.setKeyInfo(builderKeyInfo);
1409 }
1410
1411 builderKeyInfo.add(encryptedKey);
1412 }
1413
1414 cipher.doFinal(document, elementToEncrypt, content);
1415 }
1416
1417 private WSHandlerResult createAndVerifyMessage(
1418 CallbackHandler samlCallbackHandler, boolean success
1419 ) throws Exception {
1420 SAMLCallback samlCallback = new SAMLCallback();
1421 SAMLUtil.doSAMLCallback(samlCallbackHandler, samlCallback);
1422 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
1423
1424 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
1425 WSSecHeader secHeader = new WSSecHeader(doc);
1426 secHeader.insertSecurityHeader();
1427
1428 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
1429
1430 Document unsignedDoc = wsSign.build(samlAssertion);
1431
1432 if (LOG.isDebugEnabled()) {
1433 String outputString =
1434 XMLUtils.prettyDocumentToString(unsignedDoc);
1435 LOG.debug(outputString);
1436 }
1437
1438 try {
1439 WSHandlerResult results = verify(unsignedDoc);
1440 if (!success) {
1441 fail("Failure expected in processing the SAML assertion");
1442 }
1443 return results;
1444 } catch (WSSecurityException ex) {
1445 assertFalse(success);
1446 assertTrue(ex.getMessage().contains("SAML token security failure"));
1447 return null;
1448 }
1449 }
1450
1451
1452
1453
1454
1455
1456
1457
1458 private WSHandlerResult verify(Document doc) throws Exception {
1459 RequestData requestData = new RequestData();
1460 requestData.setValidateSamlSubjectConfirmation(false);
1461
1462 WSHandlerResult results = secEngine.processSecurityHeader(doc, requestData);
1463 String outputString =
1464 XMLUtils.prettyDocumentToString(doc);
1465 assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : false);
1466 return results;
1467 }
1468
1469 }