1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.ws.security.saml;
21
22 import org.apache.ws.security.WSConstants;
23 import org.apache.ws.security.WSDataRef;
24 import org.apache.ws.security.WSEncryptionPart;
25 import org.apache.ws.security.WSSConfig;
26 import org.apache.ws.security.WSSecurityEngine;
27 import org.apache.ws.security.WSSecurityEngineResult;
28 import org.apache.ws.security.common.KeystoreCallbackHandler;
29 import org.apache.ws.security.common.SAML1CallbackHandler;
30 import org.apache.ws.security.common.SAML2CallbackHandler;
31 import org.apache.ws.security.common.SOAPUtil;
32 import org.apache.ws.security.components.crypto.Crypto;
33 import org.apache.ws.security.components.crypto.CryptoFactory;
34 import org.apache.ws.security.components.crypto.Merlin;
35 import org.apache.ws.security.message.WSSecEncrypt;
36 import org.apache.ws.security.message.WSSecHeader;
37 import org.apache.ws.security.saml.ext.AssertionWrapper;
38 import org.apache.ws.security.saml.ext.SAMLParms;
39 import org.apache.ws.security.saml.ext.builder.SAML1Constants;
40 import org.apache.ws.security.saml.ext.builder.SAML2Constants;
41 import org.apache.ws.security.util.Loader;
42 import org.apache.ws.security.util.WSSecurityUtil;
43
44 import org.w3c.dom.Document;
45 import org.w3c.dom.Element;
46 import org.w3c.dom.Node;
47
48 import java.io.InputStream;
49 import java.security.KeyStore;
50 import java.util.List;
51 import java.util.ArrayList;
52
53 import javax.security.auth.callback.CallbackHandler;
54
55
56
57
58 public class SamlReferenceTest extends org.junit.Assert {
59 private static final org.apache.commons.logging.Log LOG =
60 org.apache.commons.logging.LogFactory.getLog(SamlReferenceTest.class);
61 private WSSecurityEngine secEngine = new WSSecurityEngine();
62 private CallbackHandler callbackHandler = new KeystoreCallbackHandler();
63 private Crypto crypto = CryptoFactory.getInstance("crypto.properties");
64 private Crypto trustCrypto = null;
65 private Crypto issuerCrypto = null;
66 private Crypto userCrypto = CryptoFactory.getInstance("wss40.properties");
67
68 public SamlReferenceTest() throws Exception {
69 WSSConfig.init();
70
71 issuerCrypto = new Merlin();
72 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
73 ClassLoader loader = Loader.getClassLoader(SignedSamlTokenHOKTest.class);
74 InputStream input = Merlin.loadInputStream(loader, "keys/wss40_server.jks");
75 keyStore.load(input, "security".toCharArray());
76 ((Merlin)issuerCrypto).setKeyStore(keyStore);
77
78
79 trustCrypto = new Merlin();
80 KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
81 input = Merlin.loadInputStream(loader, "keys/wss40CA.jks");
82 trustStore.load(input, "security".toCharArray());
83 ((Merlin)trustCrypto).setTrustStore(trustStore);
84 }
85
86
87
88
89
90
91 @org.junit.Test
92 @SuppressWarnings("unchecked")
93 public void testSAML1SVKeyIdentifier() throws Exception {
94 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
95 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
96 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
97 callbackHandler.setIssuer("www.example.com");
98
99 SAMLParms samlParms = new SAMLParms();
100 samlParms.setCallbackHandler(callbackHandler);
101 AssertionWrapper assertion = new AssertionWrapper(samlParms);
102
103 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
104 WSSecHeader secHeader = new WSSecHeader();
105 secHeader.insertSecurityHeader(doc);
106
107 WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
108 wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
109 Document signedDoc =
110 wsSign.build(
111 doc, null, assertion, crypto, "16c73ab6-b892-458f-abf5-2f875f74882e",
112 "security", secHeader
113 );
114
115 String outputString =
116 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
117 if (LOG.isDebugEnabled()) {
118 LOG.debug("Signed SAML message Key Identifier (sender vouches):");
119 LOG.debug(outputString);
120 }
121 assertTrue(outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE));
122 assertTrue(outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE));
123
124 List<WSSecurityEngineResult> results = verify(signedDoc, crypto, null);
125 WSSecurityEngineResult actionResult =
126 WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
127 AssertionWrapper receivedAssertion =
128 (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
129 assertTrue(receivedAssertion != null);
130
131
132 actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
133 assertTrue(actionResult != null);
134 assertFalse(actionResult.isEmpty());
135 final List<WSDataRef> refs =
136 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
137 assertTrue(refs.size() == 2);
138
139 WSDataRef wsDataRef = (WSDataRef)refs.get(0);
140 String xpath = wsDataRef.getXpath();
141 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
142
143 wsDataRef = (WSDataRef)refs.get(1);
144 xpath = wsDataRef.getXpath();
145 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml1:Assertion", xpath);
146 }
147
148
149
150
151
152
153
154 @org.junit.Test
155 @SuppressWarnings("unchecked")
156 public void testSAML1SVDirectReference() throws Exception {
157 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
158 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
159 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
160 callbackHandler.setIssuer("www.example.com");
161
162 SAMLParms samlParms = new SAMLParms();
163 samlParms.setCallbackHandler(callbackHandler);
164 AssertionWrapper assertion = new AssertionWrapper(samlParms);
165
166 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
167 WSSecHeader secHeader = new WSSecHeader();
168 secHeader.insertSecurityHeader(doc);
169
170 WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
171 wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
172 wsSign.setUseDirectReferenceToAssertion(true);
173 Document signedDoc =
174 wsSign.build(
175 doc, null, assertion, crypto, "16c73ab6-b892-458f-abf5-2f875f74882e",
176 "security", secHeader
177 );
178
179 String outputString =
180 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
181 if (LOG.isDebugEnabled()) {
182 LOG.debug("Signed SAML message Direct Reference (sender vouches):");
183 LOG.debug(outputString);
184 }
185 assertTrue(outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE));
186 assertTrue(outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE));
187
188 List<WSSecurityEngineResult> results = verify(signedDoc, crypto, null);
189 WSSecurityEngineResult actionResult =
190 WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
191 AssertionWrapper receivedAssertion =
192 (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
193 assertTrue(receivedAssertion != null);
194
195
196 actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
197 assertTrue(actionResult != null);
198 assertFalse(actionResult.isEmpty());
199 final List<WSDataRef> refs =
200 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
201 assertTrue(refs.size() == 2);
202
203 WSDataRef wsDataRef = (WSDataRef)refs.get(0);
204 String xpath = wsDataRef.getXpath();
205 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
206
207 wsDataRef = (WSDataRef)refs.get(1);
208 xpath = wsDataRef.getXpath();
209 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml1:Assertion", xpath);
210 }
211
212
213
214
215
216
217
218 @org.junit.Test
219 @SuppressWarnings("unchecked")
220 public void testSAML1HOKKeyIdentifier() throws Exception {
221 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
222 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
223 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
224 callbackHandler.setIssuer("www.example.com");
225
226 SAMLParms samlParms = new SAMLParms();
227 samlParms.setCallbackHandler(callbackHandler);
228 AssertionWrapper assertion = new AssertionWrapper(samlParms);
229 assertion.signAssertion("wss40_server", "security", issuerCrypto, false);
230
231 WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
232 wsSign.setUserInfo("wss40", "security");
233 wsSign.setDigestAlgo("http://www.w3.org/2001/04/xmlenc#sha256");
234 wsSign.setSignatureAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
235
236 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
237 WSSecHeader secHeader = new WSSecHeader();
238 secHeader.insertSecurityHeader(doc);
239
240 Document signedDoc =
241 wsSign.build(doc, userCrypto, assertion, null, null, null, secHeader);
242
243 String outputString =
244 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
245 if (LOG.isDebugEnabled()) {
246 LOG.debug("Signed SAML message Key Identifier (holder-of-key):");
247 LOG.debug(outputString);
248 }
249 assertTrue(outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE));
250 assertTrue(outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE));
251
252 List<WSSecurityEngineResult> results = verify(signedDoc, trustCrypto, null);
253 WSSecurityEngineResult actionResult =
254 WSSecurityUtil.fetchActionResult(results, WSConstants.ST_SIGNED);
255 AssertionWrapper receivedAssertion =
256 (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
257 assertTrue(receivedAssertion != null);
258 assertTrue(receivedAssertion.isSigned());
259
260
261 actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
262 assertTrue(actionResult != null);
263 assertFalse(actionResult.isEmpty());
264 final List<WSDataRef> refs =
265 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
266 assertTrue(refs.size() == 1);
267
268 WSDataRef wsDataRef = (WSDataRef)refs.get(0);
269 String xpath = wsDataRef.getXpath();
270 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
271 }
272
273
274
275
276
277
278
279
280 @org.junit.Test
281 @SuppressWarnings("unchecked")
282 public void testSAML1HOKDirectReference() throws Exception {
283 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
284 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
285 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
286 callbackHandler.setIssuer("www.example.com");
287
288 SAMLParms samlParms = new SAMLParms();
289 samlParms.setCallbackHandler(callbackHandler);
290 AssertionWrapper assertion = new AssertionWrapper(samlParms);
291 assertion.signAssertion("wss40_server", "security", issuerCrypto, false);
292
293 WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
294 wsSign.setUserInfo("wss40", "security");
295 wsSign.setDigestAlgo("http://www.w3.org/2001/04/xmlenc#sha256");
296 wsSign.setSignatureAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
297 wsSign.setUseDirectReferenceToAssertion(true);
298 wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
299
300 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
301 WSSecHeader secHeader = new WSSecHeader();
302 secHeader.insertSecurityHeader(doc);
303
304 Document signedDoc =
305 wsSign.build(doc, userCrypto, assertion, null, null, null, secHeader);
306
307 String outputString =
308 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
309 if (LOG.isDebugEnabled()) {
310 LOG.debug("Signed SAML message Direct Reference (holder-of-key):");
311 LOG.debug(outputString);
312 }
313 assertTrue(outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE));
314 assertTrue(outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE));
315
316 List<WSSecurityEngineResult> results = verify(signedDoc, trustCrypto, null);
317 WSSecurityEngineResult actionResult =
318 WSSecurityUtil.fetchActionResult(results, WSConstants.ST_SIGNED);
319 AssertionWrapper receivedAssertion =
320 (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
321 assertTrue(receivedAssertion != null);
322 assertTrue(receivedAssertion.isSigned());
323
324
325 actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
326 assertTrue(actionResult != null);
327 assertFalse(actionResult.isEmpty());
328 final List<WSDataRef> refs =
329 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
330 assertTrue(refs.size() == 1);
331
332 WSDataRef wsDataRef = (WSDataRef)refs.get(0);
333 String xpath = wsDataRef.getXpath();
334 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
335 }
336
337
338
339
340
341
342
343
344
345
346 @org.junit.Test
347 public void testAssertionBelowSTR() throws Exception {
348 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
349 WSSecHeader secHeader = new WSSecHeader();
350 secHeader.insertSecurityHeader(doc);
351
352 SAMLIssuer saml = SAMLIssuerFactory.getInstance("saml_sv.properties");
353 AssertionWrapper assertion = saml.newAssertion();
354 Crypto crypto = CryptoFactory.getInstance("crypto.properties");
355 WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
356 wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
357 Document samlDoc =
358 wsSign.build(doc, null, assertion, crypto,
359 "16c73ab6-b892-458f-abf5-2f875f74882e", "security", secHeader
360 );
361
362 WSSecEncrypt builder = new WSSecEncrypt();
363 builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e");
364 builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
365 Document encryptedDoc = builder.build(samlDoc, crypto, secHeader);
366
367
368
369
370 org.w3c.dom.Element secHeaderElement = secHeader.getSecurityHeader();
371 org.w3c.dom.Node assertionNode =
372 secHeaderElement.getElementsByTagNameNS(WSConstants.SAML_NS, "Assertion").item(0);
373 secHeaderElement.removeChild(assertionNode);
374 secHeaderElement.appendChild(assertionNode);
375
376 String outputString =
377 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(encryptedDoc);
378 if (LOG.isDebugEnabled()) {
379 LOG.debug("Encrypted message:");
380 LOG.debug(outputString);
381 }
382 assertTrue(outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE));
383 assertTrue(outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE));
384
385 verify(encryptedDoc, crypto, crypto);
386 }
387
388
389
390
391
392
393
394
395 @org.junit.Test
396 @SuppressWarnings("unchecked")
397 public void testSAML1HOKEKKeyIdentifier() throws Exception {
398
399 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
400 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
401 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
402 callbackHandler.setIssuer("www.example.com");
403
404 SAMLParms samlParms = new SAMLParms();
405 samlParms.setCallbackHandler(callbackHandler);
406 AssertionWrapper assertion = new AssertionWrapper(samlParms);
407 assertion.signAssertion("wss40_server", "security", issuerCrypto, false);
408
409 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
410 WSSecHeader secHeader = new WSSecHeader();
411 Node assertionNode = assertion.toDOM(doc);
412 secHeader.insertSecurityHeader(doc);
413 secHeader.getSecurityHeader().appendChild(assertionNode);
414
415
416 WSSecEncrypt builder = new WSSecEncrypt();
417 builder.setUserInfo("wss40");
418 builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
419 builder.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
420 builder.setCustomEKTokenValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
421 builder.setCustomEKTokenId(assertion.getId());
422 builder.prepare(doc, userCrypto);
423
424 List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
425 WSEncryptionPart encP =
426 new WSEncryptionPart(
427 "add", "http://ws.apache.org/counter/counter_port_type", "Element"
428 );
429 parts.add(encP);
430 Element refElement = builder.encryptForRef(null, parts);
431 builder.addInternalRefElement(refElement);
432 builder.appendToHeader(secHeader);
433
434 String outputString =
435 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
436 if (LOG.isDebugEnabled()) {
437 LOG.debug("Encrypted SAML 1.1 message Key Identifier (holder-of-key):");
438 LOG.debug(outputString);
439 }
440 assertTrue(outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE));
441 assertTrue(outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE));
442
443 List<WSSecurityEngineResult> results = verify(doc, trustCrypto, userCrypto);
444 WSSecurityEngineResult actionResult =
445 WSSecurityUtil.fetchActionResult(results, WSConstants.ST_SIGNED);
446 AssertionWrapper receivedAssertion =
447 (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
448 assertTrue(receivedAssertion != null);
449 assertTrue(receivedAssertion.isSigned());
450
451
452 actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.ENCR);
453 assertTrue(actionResult != null);
454 assertFalse(actionResult.isEmpty());
455 final List<WSDataRef> refs =
456 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
457 assertTrue(refs.size() == 1);
458
459 WSDataRef wsDataRef = (WSDataRef)refs.get(0);
460 String xpath = wsDataRef.getXpath();
461 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body/add", xpath);
462
463 }
464
465
466
467
468
469
470
471
472 @org.junit.Test
473 @SuppressWarnings("unchecked")
474 public void testSAML1HOKEKDirectReference() throws Exception {
475
476 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
477 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
478 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
479 callbackHandler.setIssuer("www.example.com");
480
481 SAMLParms samlParms = new SAMLParms();
482 samlParms.setCallbackHandler(callbackHandler);
483 AssertionWrapper assertion = new AssertionWrapper(samlParms);
484 assertion.signAssertion("wss40_server", "security", issuerCrypto, false);
485 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
486 WSSecHeader secHeader = new WSSecHeader();
487 Node assertionNode = assertion.toDOM(doc);
488 secHeader.insertSecurityHeader(doc);
489 secHeader.getSecurityHeader().appendChild(assertionNode);
490
491
492 WSSecEncrypt builder = new WSSecEncrypt();
493 builder.setUserInfo("wss40");
494 builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
495 builder.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING);
496 builder.setCustomEKTokenValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
497 builder.setCustomEKTokenId(assertion.getId());
498 builder.prepare(doc, userCrypto);
499
500 List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
501 WSEncryptionPart encP =
502 new WSEncryptionPart(
503 "add", "http://ws.apache.org/counter/counter_port_type", "Element"
504 );
505 parts.add(encP);
506 Element refElement = builder.encryptForRef(null, parts);
507 builder.addInternalRefElement(refElement);
508 builder.appendToHeader(secHeader);
509
510 String outputString =
511 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
512 if (LOG.isDebugEnabled()) {
513 LOG.debug("Encrypted SAML 1.1 message Direct Reference (holder-of-key):");
514 LOG.debug(outputString);
515 }
516 assertTrue(outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE));
517 assertTrue(outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE));
518
519 List<WSSecurityEngineResult> results = verify(doc, trustCrypto, userCrypto);
520 WSSecurityEngineResult actionResult =
521 WSSecurityUtil.fetchActionResult(results, WSConstants.ST_SIGNED);
522 AssertionWrapper receivedAssertion =
523 (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
524 assertTrue(receivedAssertion != null);
525 assertTrue(receivedAssertion.isSigned());
526
527
528 actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.ENCR);
529 assertTrue(actionResult != null);
530 assertFalse(actionResult.isEmpty());
531 final List<WSDataRef> refs =
532 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
533 assertTrue(refs.size() == 1);
534
535 WSDataRef wsDataRef = (WSDataRef)refs.get(0);
536 String xpath = wsDataRef.getXpath();
537 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body/add", xpath);
538 }
539
540
541
542
543
544
545 @org.junit.Test
546 @SuppressWarnings("unchecked")
547 public void testSAML2SVKeyIdentifier() throws Exception {
548 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
549 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
550 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
551 callbackHandler.setIssuer("www.example.com");
552
553 SAMLParms samlParms = new SAMLParms();
554 samlParms.setCallbackHandler(callbackHandler);
555 AssertionWrapper assertion = new AssertionWrapper(samlParms);
556
557 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
558 WSSecHeader secHeader = new WSSecHeader();
559 secHeader.insertSecurityHeader(doc);
560
561 WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
562 wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
563 Document signedDoc =
564 wsSign.build(
565 doc, null, assertion, crypto, "16c73ab6-b892-458f-abf5-2f875f74882e",
566 "security", secHeader
567 );
568
569 String outputString =
570 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
571 if (LOG.isDebugEnabled()) {
572 LOG.debug("Signed SAML2 message Key Identifier (sender vouches):");
573 LOG.debug(outputString);
574 }
575 assertTrue(outputString.contains(WSConstants.WSS_SAML2_KI_VALUE_TYPE));
576 assertTrue(outputString.contains(WSConstants.WSS_SAML2_TOKEN_TYPE));
577
578 List<WSSecurityEngineResult> results = verify(signedDoc, crypto, null);
579 WSSecurityEngineResult actionResult =
580 WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
581 AssertionWrapper receivedAssertion =
582 (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
583 assertTrue(receivedAssertion != null);
584
585
586 actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
587 assertTrue(actionResult != null);
588 assertFalse(actionResult.isEmpty());
589 final List<WSDataRef> refs =
590 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
591 assertTrue(refs.size() == 2);
592
593 WSDataRef wsDataRef = (WSDataRef)refs.get(0);
594 String xpath = wsDataRef.getXpath();
595 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
596
597 wsDataRef = (WSDataRef)refs.get(1);
598 xpath = wsDataRef.getXpath();
599 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml2:Assertion", xpath);
600 }
601
602
603
604
605
606
607 @org.junit.Test
608 @SuppressWarnings("unchecked")
609 public void testSAML2SVDirectReference() throws Exception {
610 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
611 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
612 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
613 callbackHandler.setIssuer("www.example.com");
614
615 SAMLParms samlParms = new SAMLParms();
616 samlParms.setCallbackHandler(callbackHandler);
617 AssertionWrapper assertion = new AssertionWrapper(samlParms);
618
619 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
620 WSSecHeader secHeader = new WSSecHeader();
621 secHeader.insertSecurityHeader(doc);
622
623 WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
624 wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
625 wsSign.setUseDirectReferenceToAssertion(true);
626 Document signedDoc =
627 wsSign.build(
628 doc, null, assertion, crypto, "16c73ab6-b892-458f-abf5-2f875f74882e",
629 "security", secHeader
630 );
631
632 String outputString =
633 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
634 if (LOG.isDebugEnabled()) {
635 LOG.debug("Signed SAML2 message Direct Reference (sender vouches):");
636 LOG.debug(outputString);
637 }
638 assertTrue(!outputString.contains(WSConstants.WSS_SAML2_KI_VALUE_TYPE));
639 assertTrue(outputString.contains(WSConstants.WSS_SAML2_TOKEN_TYPE));
640
641 List<WSSecurityEngineResult> results = verify(signedDoc, crypto, null);
642 WSSecurityEngineResult actionResult =
643 WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
644 AssertionWrapper receivedAssertion =
645 (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
646 assertTrue(receivedAssertion != null);
647
648
649 actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
650 assertTrue(actionResult != null);
651 assertFalse(actionResult.isEmpty());
652 final List<WSDataRef> refs =
653 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
654 assertTrue(refs.size() == 2);
655
656 WSDataRef wsDataRef = (WSDataRef)refs.get(0);
657 String xpath = wsDataRef.getXpath();
658 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
659
660 wsDataRef = (WSDataRef)refs.get(1);
661 xpath = wsDataRef.getXpath();
662 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml2:Assertion", xpath);
663 }
664
665
666
667
668
669
670
671 @org.junit.Test
672 @SuppressWarnings("unchecked")
673 public void testSAML2HOKKeyIdentifier() throws Exception {
674 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
675 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
676 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
677 callbackHandler.setIssuer("www.example.com");
678
679 SAMLParms samlParms = new SAMLParms();
680 samlParms.setCallbackHandler(callbackHandler);
681 AssertionWrapper assertion = new AssertionWrapper(samlParms);
682 assertion.signAssertion("wss40_server", "security", issuerCrypto, false);
683
684 WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
685 wsSign.setUserInfo("wss40", "security");
686 wsSign.setDigestAlgo("http://www.w3.org/2001/04/xmlenc#sha256");
687 wsSign.setSignatureAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
688
689 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
690 WSSecHeader secHeader = new WSSecHeader();
691 secHeader.insertSecurityHeader(doc);
692
693 Document signedDoc =
694 wsSign.build(doc, userCrypto, assertion, null, null, null, secHeader);
695
696 String outputString =
697 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
698 if (LOG.isDebugEnabled()) {
699 LOG.debug("Signed SAML2 message Key Identifier (holder-of-key):");
700 LOG.debug(outputString);
701 }
702 assertTrue(outputString.contains(WSConstants.WSS_SAML2_KI_VALUE_TYPE));
703 assertTrue(outputString.contains(WSConstants.WSS_SAML2_TOKEN_TYPE));
704
705 List<WSSecurityEngineResult> results = verify(signedDoc, trustCrypto, null);
706 WSSecurityEngineResult actionResult =
707 WSSecurityUtil.fetchActionResult(results, WSConstants.ST_SIGNED);
708 AssertionWrapper receivedAssertion =
709 (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
710 assertTrue(receivedAssertion != null);
711 assertTrue(receivedAssertion.isSigned());
712
713
714 actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
715 assertTrue(actionResult != null);
716 assertFalse(actionResult.isEmpty());
717 final List<WSDataRef> refs =
718 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
719 assertTrue(refs.size() == 1);
720
721 WSDataRef wsDataRef = (WSDataRef)refs.get(0);
722 String xpath = wsDataRef.getXpath();
723 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
724 }
725
726
727
728
729
730
731
732
733 @org.junit.Test
734 @SuppressWarnings("unchecked")
735 public void testSAML2HOKDirectReference() throws Exception {
736 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
737 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
738 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
739 callbackHandler.setIssuer("www.example.com");
740
741 SAMLParms samlParms = new SAMLParms();
742 samlParms.setCallbackHandler(callbackHandler);
743 AssertionWrapper assertion = new AssertionWrapper(samlParms);
744 assertion.signAssertion("wss40_server", "security", issuerCrypto, false);
745
746 WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
747 wsSign.setUserInfo("wss40", "security");
748 wsSign.setDigestAlgo("http://www.w3.org/2001/04/xmlenc#sha256");
749 wsSign.setSignatureAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
750 wsSign.setUseDirectReferenceToAssertion(true);
751 wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
752
753 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
754 WSSecHeader secHeader = new WSSecHeader();
755 secHeader.insertSecurityHeader(doc);
756
757 Document signedDoc =
758 wsSign.build(doc, userCrypto, assertion, null, null, null, secHeader);
759
760 String outputString =
761 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
762 if (LOG.isDebugEnabled()) {
763 LOG.debug("Signed SAML2 message Direct Reference (holder-of-key):");
764 LOG.debug(outputString);
765 }
766 assertTrue(!outputString.contains(WSConstants.WSS_SAML2_KI_VALUE_TYPE));
767 assertTrue(outputString.contains(WSConstants.WSS_SAML2_TOKEN_TYPE));
768
769 List<WSSecurityEngineResult> results = verify(signedDoc, trustCrypto, null);
770 WSSecurityEngineResult actionResult =
771 WSSecurityUtil.fetchActionResult(results, WSConstants.ST_SIGNED);
772 AssertionWrapper receivedAssertion =
773 (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
774 assertTrue(receivedAssertion != null);
775 assertTrue(receivedAssertion.isSigned());
776
777
778 actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
779 assertTrue(actionResult != null);
780 assertFalse(actionResult.isEmpty());
781 final List<WSDataRef> refs =
782 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
783 assertTrue(refs.size() == 1);
784
785 WSDataRef wsDataRef = (WSDataRef)refs.get(0);
786 String xpath = wsDataRef.getXpath();
787 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
788 }
789
790
791
792
793
794
795
796 @org.junit.Test
797 @SuppressWarnings("unchecked")
798 public void testSAML2HOKEKKeyIdentifier() throws Exception {
799
800 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
801 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
802 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
803 callbackHandler.setIssuer("www.example.com");
804
805 SAMLParms samlParms = new SAMLParms();
806 samlParms.setCallbackHandler(callbackHandler);
807 AssertionWrapper assertion = new AssertionWrapper(samlParms);
808 assertion.signAssertion("wss40_server", "security", issuerCrypto, false);
809
810 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
811 WSSecHeader secHeader = new WSSecHeader();
812 Node assertionNode = assertion.toDOM(doc);
813 secHeader.insertSecurityHeader(doc);
814 secHeader.getSecurityHeader().appendChild(assertionNode);
815
816
817 WSSecEncrypt builder = new WSSecEncrypt();
818 builder.setUserInfo("wss40");
819 builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
820 builder.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
821 builder.setCustomEKTokenValueType(WSConstants.WSS_SAML2_KI_VALUE_TYPE);
822 builder.setCustomEKTokenId(assertion.getId());
823 builder.prepare(doc, userCrypto);
824
825 List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
826 WSEncryptionPart encP =
827 new WSEncryptionPart(
828 "add", "http://ws.apache.org/counter/counter_port_type", "Element"
829 );
830 parts.add(encP);
831 Element refElement = builder.encryptForRef(null, parts);
832 builder.addInternalRefElement(refElement);
833 builder.appendToHeader(secHeader);
834
835 String outputString =
836 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
837 if (LOG.isDebugEnabled()) {
838 LOG.debug("Encrypted SAML 2 message Key Identifier (holder-of-key):");
839 LOG.debug(outputString);
840 }
841 assertTrue(outputString.contains(WSConstants.WSS_SAML2_KI_VALUE_TYPE));
842 assertTrue(outputString.contains(WSConstants.WSS_SAML2_TOKEN_TYPE));
843
844 List<WSSecurityEngineResult> results = verify(doc, trustCrypto, userCrypto);
845 WSSecurityEngineResult actionResult =
846 WSSecurityUtil.fetchActionResult(results, WSConstants.ST_SIGNED);
847 AssertionWrapper receivedAssertion =
848 (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
849 assertTrue(receivedAssertion != null);
850 assertTrue(receivedAssertion.isSigned());
851
852
853 actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.ENCR);
854 assertTrue(actionResult != null);
855 assertFalse(actionResult.isEmpty());
856 final List<WSDataRef> refs =
857 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
858 assertTrue(refs.size() == 1);
859
860 WSDataRef wsDataRef = (WSDataRef)refs.get(0);
861 String xpath = wsDataRef.getXpath();
862 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body/add", xpath);
863
864 }
865
866
867
868
869
870
871
872 @org.junit.Test
873 @SuppressWarnings("unchecked")
874 public void testSAML2HOKEKDirectReference() throws Exception {
875
876 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
877 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
878 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
879 callbackHandler.setIssuer("www.example.com");
880
881 SAMLParms samlParms = new SAMLParms();
882 samlParms.setCallbackHandler(callbackHandler);
883 AssertionWrapper assertion = new AssertionWrapper(samlParms);
884 assertion.signAssertion("wss40_server", "security", issuerCrypto, false);
885
886 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
887 WSSecHeader secHeader = new WSSecHeader();
888 Node assertionNode = assertion.toDOM(doc);
889 secHeader.insertSecurityHeader(doc);
890 secHeader.getSecurityHeader().appendChild(assertionNode);
891
892
893 WSSecEncrypt builder = new WSSecEncrypt();
894 builder.setUserInfo("wss40");
895 builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
896 builder.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING);
897 builder.setCustomEKTokenValueType(WSConstants.WSS_SAML2_KI_VALUE_TYPE);
898 builder.setCustomEKTokenId(assertion.getId());
899 builder.prepare(doc, userCrypto);
900
901 List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
902 WSEncryptionPart encP =
903 new WSEncryptionPart(
904 "add", "http://ws.apache.org/counter/counter_port_type", "Element"
905 );
906 parts.add(encP);
907 Element refElement = builder.encryptForRef(null, parts);
908 builder.addInternalRefElement(refElement);
909 builder.appendToHeader(secHeader);
910
911 String outputString =
912 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
913 if (LOG.isDebugEnabled()) {
914 LOG.debug("Encrypted SAML 2 message Direct Reference (holder-of-key):");
915 LOG.debug(outputString);
916 }
917 assertTrue(!outputString.contains(WSConstants.WSS_SAML2_KI_VALUE_TYPE));
918 assertTrue(outputString.contains(WSConstants.WSS_SAML2_TOKEN_TYPE));
919
920 List<WSSecurityEngineResult> results = verify(doc, trustCrypto, userCrypto);
921 WSSecurityEngineResult actionResult =
922 WSSecurityUtil.fetchActionResult(results, WSConstants.ST_SIGNED);
923 AssertionWrapper receivedAssertion =
924 (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
925 assertTrue(receivedAssertion != null);
926 assertTrue(receivedAssertion.isSigned());
927
928
929 actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.ENCR);
930 assertTrue(actionResult != null);
931 assertFalse(actionResult.isEmpty());
932 final List<WSDataRef> refs =
933 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
934 assertTrue(refs.size() == 1);
935
936 WSDataRef wsDataRef = (WSDataRef)refs.get(0);
937 String xpath = wsDataRef.getXpath();
938 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body/add", xpath);
939
940 }
941
942
943
944
945
946
947
948
949 private List<WSSecurityEngineResult> verify(
950 Document doc, Crypto verifyCrypto, Crypto decCrypto
951 ) throws Exception {
952 List<WSSecurityEngineResult> results =
953 secEngine.processSecurityHeader(doc, null, callbackHandler, verifyCrypto, decCrypto);
954 String outputString =
955 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
956 assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : false);
957 return results;
958 }
959
960 }