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.time.Duration;
23 import java.time.Instant;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.List;
27
28 import javax.security.auth.callback.CallbackHandler;
29
30 import org.apache.wss4j.common.ext.WSSecurityException;
31 import org.apache.wss4j.common.saml.SAMLCallback;
32 import org.apache.wss4j.common.saml.SAMLUtil;
33 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
34 import org.apache.wss4j.common.saml.bean.AudienceRestrictionBean;
35 import org.apache.wss4j.common.saml.bean.ConditionsBean;
36 import org.apache.wss4j.common.saml.bean.DelegateBean;
37 import org.apache.wss4j.common.saml.bean.NameIDBean;
38 import org.apache.wss4j.common.saml.bean.ProxyRestrictionBean;
39 import org.apache.wss4j.common.saml.builder.SAML2Constants;
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.CustomSamlAssertionValidator;
44 import org.apache.wss4j.dom.common.SAML1CallbackHandler;
45 import org.apache.wss4j.dom.common.SAML2CallbackHandler;
46
47 import org.apache.wss4j.dom.engine.WSSConfig;
48 import org.apache.wss4j.dom.engine.WSSecurityEngine;
49 import org.apache.wss4j.dom.handler.RequestData;
50 import org.apache.wss4j.dom.handler.WSHandlerResult;
51 import org.apache.wss4j.dom.message.WSSecHeader;
52 import org.apache.wss4j.dom.message.WSSecSAMLToken;
53
54 import org.junit.jupiter.api.Test;
55 import org.w3c.dom.Document;
56
57 import static org.junit.jupiter.api.Assertions.assertFalse;
58 import static org.junit.jupiter.api.Assertions.assertTrue;
59 import static org.junit.jupiter.api.Assertions.fail;
60
61
62
63
64 public class SamlConditionsTest {
65 private static final org.slf4j.Logger LOG =
66 org.slf4j.LoggerFactory.getLogger(SamlConditionsTest.class);
67 private WSSecurityEngine secEngine = new WSSecurityEngine();
68
69 public SamlConditionsTest() {
70 WSSConfig config = WSSConfig.getNewInstance();
71 config.setValidator(WSConstants.SAML_TOKEN, new CustomSamlAssertionValidator());
72 config.setValidator(WSConstants.SAML2_TOKEN, new CustomSamlAssertionValidator());
73 secEngine.setWssConfig(config);
74 }
75
76
77
78
79
80 @Test
81 public void testSAML1Conditions() throws Exception {
82 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
83 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
84 callbackHandler.setIssuer("www.example.com");
85
86 ConditionsBean conditions = new ConditionsBean();
87 Instant notBefore = Instant.now();
88 conditions.setNotBefore(notBefore);
89 conditions.setNotAfter(notBefore.plus(Duration.ofMinutes(20)));
90 callbackHandler.setConditions(conditions);
91
92 createAndVerifyMessage(callbackHandler, true);
93 }
94
95
96
97
98
99 @Test
100 public void testSAML2InvalidAfterConditions() throws Exception {
101 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
102 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
103 callbackHandler.setIssuer("www.example.com");
104
105 ConditionsBean conditions = new ConditionsBean();
106 Instant notBefore = Instant.now();
107 conditions.setNotBefore(notBefore.minus(Duration.ofMinutes(5)));
108 conditions.setNotAfter(notBefore.minus(Duration.ofMinutes(3)));
109 callbackHandler.setConditions(conditions);
110
111 createAndVerifyMessage(callbackHandler, false);
112 }
113
114 @Test
115 public void testSAML2StaleNotOnOrAfter() throws Exception {
116 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
117 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
118 callbackHandler.setIssuer("www.example.com");
119
120 ConditionsBean conditions = new ConditionsBean();
121 Instant notBefore = Instant.now();
122 conditions.setNotAfter(notBefore.minus(Duration.ofMinutes(60)));
123 conditions.setNotBefore(notBefore.minus(Duration.ofMinutes(70)));
124 callbackHandler.setConditions(conditions);
125
126 createAndVerifyMessage(callbackHandler, false);
127 }
128
129 @Test
130 public void testSAML2FutureNotBefore() throws Exception {
131 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
132 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
133 callbackHandler.setIssuer("www.example.com");
134
135 ConditionsBean conditions = new ConditionsBean();
136 Instant notBefore = Instant.now();
137 conditions.setNotAfter(notBefore.plus(Duration.ofMinutes(70)));
138 conditions.setNotBefore(notBefore.plus(Duration.ofMinutes(60)));
139 callbackHandler.setConditions(conditions);
140
141 createAndVerifyMessage(callbackHandler, false);
142 }
143
144 @Test
145 public void testSAML2FutureIssueInstant() throws Exception {
146 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
147 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
148 callbackHandler.setIssuer("www.example.com");
149
150 SAMLCallback samlCallback = new SAMLCallback();
151 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
152 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
153
154 Instant issueInstant = Instant.now();
155 issueInstant = issueInstant.plus(Duration.ofMinutes(60));
156 samlAssertion.getSaml2().setIssueInstant(issueInstant);
157
158 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
159 WSSecHeader secHeader = new WSSecHeader(doc);
160 secHeader.insertSecurityHeader();
161
162 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
163
164 Document unsignedDoc = wsSign.build(samlAssertion);
165
166 if (LOG.isDebugEnabled()) {
167 LOG.debug("SAML 2 Authn Assertion (sender vouches):");
168 String outputString =
169 XMLUtils.prettyDocumentToString(unsignedDoc);
170 LOG.debug(outputString);
171 }
172
173 try {
174 verify(unsignedDoc);
175 fail("Failure expected in processing the SAML Conditions element");
176 } catch (WSSecurityException ex) {
177 assertTrue(ex.getMessage().contains("SAML token security failure"));
178 }
179 }
180
181 @Test
182 public void testSAML2StaleIssueInstant() 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 Instant issueInstant = Instant.now();
192 issueInstant = issueInstant.minus(Duration.ofMinutes(31));
193 samlAssertion.getSaml2().setIssueInstant(issueInstant);
194 samlAssertion.getSaml2().getConditions().setNotOnOrAfter(null);
195
196 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
197 WSSecHeader secHeader = new WSSecHeader(doc);
198 secHeader.insertSecurityHeader();
199
200 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
201
202 Document unsignedDoc = wsSign.build(samlAssertion);
203
204 if (LOG.isDebugEnabled()) {
205 LOG.debug("SAML 2 Authn Assertion (sender vouches):");
206 String outputString =
207 XMLUtils.prettyDocumentToString(unsignedDoc);
208 LOG.debug(outputString);
209 }
210
211 try {
212 verify(unsignedDoc);
213 fail("Failure expected in processing a stale SAML Assertion");
214 } catch (WSSecurityException ex) {
215 assertTrue(ex.getMessage().contains("SAML token security failure"));
216 }
217 }
218
219 @Test
220 public void testSAML2NoNotOnOrAfter() throws Exception {
221 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
222 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
223 callbackHandler.setIssuer("www.example.com");
224
225 SAMLCallback samlCallback = new SAMLCallback();
226 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
227 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
228
229 Instant issueInstant = Instant.now().minusSeconds(5);
230 samlAssertion.getSaml2().setIssueInstant(issueInstant);
231 samlAssertion.getSaml2().getConditions().setNotOnOrAfter(null);
232
233 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
234 WSSecHeader secHeader = new WSSecHeader(doc);
235 secHeader.insertSecurityHeader();
236
237 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
238
239 Document unsignedDoc = wsSign.build(samlAssertion);
240
241 if (LOG.isDebugEnabled()) {
242 LOG.debug("SAML 2 Authn Assertion (sender vouches):");
243 String outputString =
244 XMLUtils.prettyDocumentToString(unsignedDoc);
245 LOG.debug(outputString);
246 }
247
248 verify(unsignedDoc);
249 }
250
251 @Test
252 public void testSAML2StaleIssueInstantButWithNotOnOrAfter() throws Exception {
253 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
254 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
255 callbackHandler.setIssuer("www.example.com");
256
257 SAMLCallback samlCallback = new SAMLCallback();
258 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
259 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
260
261 ConditionsBean conditions = new ConditionsBean();
262 Instant issueInstant = Instant.now();
263 conditions.setNotBefore(issueInstant);
264 conditions.setNotAfter(issueInstant.plus(Duration.ofMinutes(35)));
265
266 issueInstant = issueInstant.minus(Duration.ofMinutes(31));
267 samlAssertion.getSaml2().setIssueInstant(issueInstant);
268
269 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
270 WSSecHeader secHeader = new WSSecHeader(doc);
271 secHeader.insertSecurityHeader();
272
273 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
274
275 Document unsignedDoc = wsSign.build(samlAssertion);
276
277 if (LOG.isDebugEnabled()) {
278 LOG.debug("SAML 2 Authn Assertion (sender vouches):");
279 String outputString =
280 XMLUtils.prettyDocumentToString(unsignedDoc);
281 LOG.debug(outputString);
282 }
283
284 verify(unsignedDoc);
285 }
286
287 @Test
288 public void testSAML1StaleIssueInstant() throws Exception {
289 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
290 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
291 callbackHandler.setIssuer("www.example.com");
292
293 SAMLCallback samlCallback = new SAMLCallback();
294 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
295 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
296
297 Instant issueInstant = Instant.now();
298 issueInstant = issueInstant.minus(Duration.ofMinutes(31));
299 samlAssertion.getSaml1().setIssueInstant(issueInstant);
300 samlAssertion.getSaml1().getConditions().setNotOnOrAfter(null);
301
302 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
303 WSSecHeader secHeader = new WSSecHeader(doc);
304 secHeader.insertSecurityHeader();
305
306 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
307
308 Document unsignedDoc = wsSign.build(samlAssertion);
309
310 if (LOG.isDebugEnabled()) {
311 LOG.debug("SAML 1 Authn Assertion (sender vouches):");
312 String outputString =
313 XMLUtils.prettyDocumentToString(unsignedDoc);
314 LOG.debug(outputString);
315 }
316
317 try {
318 verify(unsignedDoc);
319 fail("Failure expected in processing a stale SAML Assertion");
320 } catch (WSSecurityException ex) {
321 assertTrue(ex.getMessage().contains("SAML token security failure"));
322 }
323 }
324
325
326
327
328
329 @Test
330 public void testSAML2InvalidBeforeConditions() throws Exception {
331 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
332 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
333 callbackHandler.setIssuer("www.example.com");
334
335 ConditionsBean conditions = new ConditionsBean();
336 Instant notBefore = Instant.now();
337 conditions.setNotBefore(notBefore.plus(Duration.ofMinutes(2)));
338 conditions.setNotAfter(notBefore.plus(Duration.ofMinutes(5)));
339 callbackHandler.setConditions(conditions);
340
341 createAndVerifyMessage(callbackHandler, false);
342 }
343
344
345
346
347
348 @Test
349 public void testSAML2FutureTTLConditions() throws Exception {
350 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
351 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
352 callbackHandler.setIssuer("www.example.com");
353
354 ConditionsBean conditions = new ConditionsBean();
355 Instant notBefore = Instant.now();
356 conditions.setNotBefore(notBefore.plusSeconds(30));
357 conditions.setNotAfter(notBefore.plus(Duration.ofMinutes(5)));
358 callbackHandler.setConditions(conditions);
359
360 createAndVerifyMessage(callbackHandler, true);
361 }
362
363
364
365
366
367 @Test
368 public void testSAML2OneTimeUse() throws Exception {
369 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
370 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
371 callbackHandler.setIssuer("www.example.com");
372
373 ConditionsBean conditions = new ConditionsBean();
374 conditions.setTokenPeriodMinutes(5);
375 conditions.setOneTimeUse(true);
376
377 callbackHandler.setConditions(conditions);
378
379 SAMLCallback samlCallback = new SAMLCallback();
380 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
381 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
382
383 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
384 WSSecHeader secHeader = new WSSecHeader(doc);
385 secHeader.insertSecurityHeader();
386
387 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
388
389 Document unsignedDoc = wsSign.build(samlAssertion);
390
391 String outputString =
392 XMLUtils.prettyDocumentToString(unsignedDoc);
393 assertTrue(outputString.contains("OneTimeUse"));
394 if (LOG.isDebugEnabled()) {
395 LOG.debug(outputString);
396 }
397
398 verify(unsignedDoc);
399 }
400
401
402
403
404
405 @Test
406 public void testSAML2ProxyRestriction() throws Exception {
407 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
408 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
409 callbackHandler.setIssuer("www.example.com");
410
411 ConditionsBean conditions = new ConditionsBean();
412 conditions.setTokenPeriodMinutes(5);
413 ProxyRestrictionBean proxyRestriction = new ProxyRestrictionBean();
414 List<String> audiences = new ArrayList<>();
415 audiences.add("http://apache.org/one");
416 audiences.add("http://apache.org/two");
417 proxyRestriction.getAudienceURIs().addAll(audiences);
418 proxyRestriction.setCount(5);
419 conditions.setProxyRestriction(proxyRestriction);
420
421 callbackHandler.setConditions(conditions);
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 assertTrue(outputString.contains("ProxyRestriction"));
438 if (LOG.isDebugEnabled()) {
439 LOG.debug(outputString);
440 }
441
442 verify(unsignedDoc);
443 }
444
445
446
447
448
449 @Test
450 public void testSAML2AudienceRestriction() throws Exception {
451 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
452 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
453 callbackHandler.setIssuer("www.example.com");
454
455 ConditionsBean conditions = new ConditionsBean();
456 conditions.setTokenPeriodMinutes(5);
457 List<String> audiences = new ArrayList<>();
458 audiences.add("http://apache.org/one");
459 audiences.add("http://apache.org/two");
460 AudienceRestrictionBean audienceRestrictionBean = new AudienceRestrictionBean();
461 audienceRestrictionBean.setAudienceURIs(audiences);
462 conditions.setAudienceRestrictions(Collections.singletonList(audienceRestrictionBean));
463
464 callbackHandler.setConditions(conditions);
465
466 SAMLCallback samlCallback = new SAMLCallback();
467 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
468 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
469
470 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
471 WSSecHeader secHeader = new WSSecHeader(doc);
472 secHeader.insertSecurityHeader();
473
474 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
475
476 Document unsignedDoc = wsSign.build(samlAssertion);
477
478 String outputString =
479 XMLUtils.prettyDocumentToString(unsignedDoc);
480 assertTrue(outputString.contains("AudienceRestriction"));
481 if (LOG.isDebugEnabled()) {
482 LOG.debug(outputString);
483 }
484
485 verify(unsignedDoc);
486 }
487
488
489 @Test
490 public void testSAML2AudienceRestrictionVerification() throws Exception {
491 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
492 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
493 callbackHandler.setIssuer("www.example.com");
494
495 ConditionsBean conditions = new ConditionsBean();
496 conditions.setTokenPeriodMinutes(5);
497 List<String> audiences = new ArrayList<>();
498 audiences.add("http://apache.org/one");
499 audiences.add("http://apache.org/two");
500 AudienceRestrictionBean audienceRestrictionBean = new AudienceRestrictionBean();
501 audienceRestrictionBean.setAudienceURIs(audiences);
502 conditions.setAudienceRestrictions(Collections.singletonList(audienceRestrictionBean));
503
504 callbackHandler.setConditions(conditions);
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 assertTrue(outputString.contains("AudienceRestriction"));
521 if (LOG.isDebugEnabled()) {
522 LOG.debug(outputString);
523 }
524
525
526 audiences.clear();
527 audiences.add("http://apache.org/three");
528
529 WSSecurityEngine newEngine = new WSSecurityEngine();
530 RequestData data = new RequestData();
531 data.setAudienceRestrictions(audiences);
532 data.setValidateSamlSubjectConfirmation(false);
533
534 try {
535 newEngine.processSecurityHeader(doc, data);
536 fail("Failure expected on a bad audience restriction");
537 } catch (WSSecurityException ex) {
538 assertTrue(ex.getMessage().contains("SAML token security failure"));
539 }
540
541
542 audiences.add("http://apache.org/one");
543 data.setAudienceRestrictions(audiences);
544
545 newEngine.processSecurityHeader(doc, data);
546 }
547
548
549 @Test
550 public void testSAML1AudienceRestrictionVerification() throws Exception {
551 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
552 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
553 callbackHandler.setIssuer("www.example.com");
554
555 ConditionsBean conditions = new ConditionsBean();
556 conditions.setTokenPeriodMinutes(5);
557 List<String> audiences = new ArrayList<>();
558 audiences.add("http://apache.org/one");
559 audiences.add("http://apache.org/two");
560 AudienceRestrictionBean audienceRestrictionBean = new AudienceRestrictionBean();
561 audienceRestrictionBean.setAudienceURIs(audiences);
562 conditions.setAudienceRestrictions(Collections.singletonList(audienceRestrictionBean));
563
564 callbackHandler.setConditions(conditions);
565
566 SAMLCallback samlCallback = new SAMLCallback();
567 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
568 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
569
570 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
571 WSSecHeader secHeader = new WSSecHeader(doc);
572 secHeader.insertSecurityHeader();
573
574 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
575
576 Document unsignedDoc = wsSign.build(samlAssertion);
577
578 String outputString =
579 XMLUtils.prettyDocumentToString(unsignedDoc);
580 assertTrue(outputString.contains("AudienceRestriction"));
581 if (LOG.isDebugEnabled()) {
582 LOG.debug(outputString);
583 }
584
585
586 audiences.clear();
587 audiences.add("http://apache.org/three");
588
589 WSSecurityEngine newEngine = new WSSecurityEngine();
590 RequestData data = new RequestData();
591 data.setAudienceRestrictions(audiences);
592 data.setValidateSamlSubjectConfirmation(false);
593
594 try {
595 newEngine.processSecurityHeader(doc, data);
596 fail("Failure expected on a bad audience restriction");
597 } catch (WSSecurityException ex) {
598 assertTrue(ex.getMessage().contains("SAML token security failure"));
599 }
600
601
602 audiences.add("http://apache.org/one");
603 data.setAudienceRestrictions(audiences);
604
605 newEngine.processSecurityHeader(doc, data);
606 }
607
608
609
610
611
612 @Test
613 public void testSAML2AudienceRestrictionSeparateRestrictions() throws Exception {
614 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
615 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
616 callbackHandler.setIssuer("www.example.com");
617
618 ConditionsBean conditions = new ConditionsBean();
619 conditions.setTokenPeriodMinutes(5);
620
621 List<AudienceRestrictionBean> audiencesRestrictions = new ArrayList<>();
622 AudienceRestrictionBean audienceRestrictionBean = new AudienceRestrictionBean();
623 audienceRestrictionBean.setAudienceURIs(Collections.singletonList("http://apache.org/one"));
624 audiencesRestrictions.add(audienceRestrictionBean);
625
626 audienceRestrictionBean = new AudienceRestrictionBean();
627 audienceRestrictionBean.setAudienceURIs(Collections.singletonList("http://apache.org/two"));
628 audiencesRestrictions.add(audienceRestrictionBean);
629
630 conditions.setAudienceRestrictions(audiencesRestrictions);
631
632 callbackHandler.setConditions(conditions);
633
634 SAMLCallback samlCallback = new SAMLCallback();
635 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
636 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
637
638 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
639 WSSecHeader secHeader = new WSSecHeader(doc);
640 secHeader.insertSecurityHeader();
641
642 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
643
644 Document unsignedDoc = wsSign.build(samlAssertion);
645
646 String outputString =
647 XMLUtils.prettyDocumentToString(unsignedDoc);
648 assertTrue(outputString.contains("AudienceRestriction"));
649 if (LOG.isDebugEnabled()) {
650 LOG.debug(outputString);
651 }
652
653 verify(unsignedDoc);
654 }
655
656
657 @Test
658 public void testSAML2AudienceRestrictionSeparateRestrictionsValidation() throws Exception {
659 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
660 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
661 callbackHandler.setIssuer("www.example.com");
662
663 ConditionsBean conditions = new ConditionsBean();
664 conditions.setTokenPeriodMinutes(5);
665
666 List<AudienceRestrictionBean> audiencesRestrictions = new ArrayList<>();
667 AudienceRestrictionBean audienceRestrictionBean = new AudienceRestrictionBean();
668 audienceRestrictionBean.setAudienceURIs(Collections.singletonList("http://apache.org/one"));
669 audiencesRestrictions.add(audienceRestrictionBean);
670
671 audienceRestrictionBean = new AudienceRestrictionBean();
672 audienceRestrictionBean.setAudienceURIs(Collections.singletonList("http://apache.org/two"));
673 audiencesRestrictions.add(audienceRestrictionBean);
674
675 conditions.setAudienceRestrictions(audiencesRestrictions);
676
677 callbackHandler.setConditions(conditions);
678
679 SAMLCallback samlCallback = new SAMLCallback();
680 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
681 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
682
683 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
684 WSSecHeader secHeader = new WSSecHeader(doc);
685 secHeader.insertSecurityHeader();
686
687 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
688
689 Document unsignedDoc = wsSign.build(samlAssertion);
690
691 String outputString =
692 XMLUtils.prettyDocumentToString(unsignedDoc);
693 assertTrue(outputString.contains("AudienceRestriction"));
694 if (LOG.isDebugEnabled()) {
695 LOG.debug(outputString);
696 }
697
698
699 List<String> audiences = new ArrayList<>();
700 audiences.add("http://apache.org/three");
701
702 WSSecurityEngine newEngine = new WSSecurityEngine();
703 RequestData data = new RequestData();
704 data.setAudienceRestrictions(audiences);
705 data.setValidateSamlSubjectConfirmation(false);
706
707 try {
708 newEngine.processSecurityHeader(doc, data);
709 fail("Failure expected on a bad audience restriction");
710 } catch (WSSecurityException ex) {
711 assertTrue(ex.getMessage().contains("SAML token security failure"));
712 }
713
714
715 audiences.add("http://apache.org/one");
716 data.setAudienceRestrictions(audiences);
717
718 newEngine.processSecurityHeader(doc, data);
719 }
720
721 @Test
722 public void testSAML2Delegate() throws Exception {
723 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
724 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
725 callbackHandler.setIssuer("www.example.com");
726
727 ConditionsBean conditions = new ConditionsBean();
728 Instant notBefore = Instant.now();
729 conditions.setNotBefore(notBefore);
730 conditions.setNotAfter(notBefore.plus(Duration.ofMinutes(20)));
731
732 DelegateBean delegate = new DelegateBean();
733 delegate.setDelegationInstant(Instant.now());
734 delegate.setConfirmationMethod(SAML2Constants.CONF_BEARER);
735
736 NameIDBean nameID = new NameIDBean();
737 nameID.setNameValue("bob");
738 nameID.setNameQualifier("www.example.com");
739 delegate.setNameIDBean(nameID);
740
741 conditions.setDelegates(Collections.singletonList(delegate));
742
743 callbackHandler.setConditions(conditions);
744
745 createAndVerifyMessage(callbackHandler, true);
746 }
747
748 private void createAndVerifyMessage(
749 CallbackHandler samlCallbackHandler, boolean success
750 ) throws Exception {
751 SAMLCallback samlCallback = new SAMLCallback();
752 SAMLUtil.doSAMLCallback(samlCallbackHandler, samlCallback);
753 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
754
755 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
756 WSSecHeader secHeader = new WSSecHeader(doc);
757 secHeader.insertSecurityHeader();
758
759 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
760
761 Document unsignedDoc = wsSign.build(samlAssertion);
762
763 if (LOG.isDebugEnabled()) {
764 String outputString =
765 XMLUtils.prettyDocumentToString(unsignedDoc);
766 LOG.debug(outputString);
767 }
768
769 try {
770 verify(unsignedDoc);
771 if (!success) {
772 fail("Failure expected in processing the SAML assertion");
773 }
774 } catch (WSSecurityException ex) {
775 assertFalse(success);
776 assertTrue(ex.getMessage().contains("SAML token security failure"));
777 }
778 }
779
780
781
782
783
784
785
786
787 private WSHandlerResult verify(Document doc) throws Exception {
788 RequestData requestData = new RequestData();
789 requestData.setValidateSamlSubjectConfirmation(false);
790
791 WSHandlerResult results = secEngine.processSecurityHeader(doc, requestData);
792 String outputString =
793 XMLUtils.prettyDocumentToString(doc);
794 assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : false);
795 return results;
796 }
797
798 }