1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.wss4j.stax.test.saml;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.InputStream;
24 import java.nio.charset.StandardCharsets;
25 import java.security.Key;
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.HashMap;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Properties;
34
35 import javax.crypto.KeyGenerator;
36 import javax.crypto.SecretKey;
37 import javax.xml.stream.XMLStreamException;
38 import javax.xml.stream.XMLStreamReader;
39 import javax.xml.stream.XMLStreamWriter;
40 import javax.xml.transform.dom.DOMSource;
41 import javax.xml.transform.stream.StreamResult;
42
43 import org.apache.wss4j.common.ConfigurationConstants;
44 import org.apache.wss4j.common.crypto.Crypto;
45 import org.apache.wss4j.common.crypto.CryptoFactory;
46 import org.apache.wss4j.common.crypto.CryptoType;
47 import org.apache.wss4j.common.saml.SAMLCallback;
48 import org.apache.wss4j.common.saml.SAMLUtil;
49 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
50 import org.apache.wss4j.common.saml.bean.Version;
51 import org.apache.wss4j.common.saml.builder.SAML1Constants;
52 import org.apache.wss4j.common.saml.builder.SAML2Constants;
53 import org.apache.wss4j.common.token.SecurityTokenReference;
54 import org.apache.wss4j.common.util.SOAPUtil;
55 import org.apache.wss4j.dom.WSConstants;
56 import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
57 import org.apache.wss4j.dom.handler.WSHandlerConstants;
58 import org.apache.wss4j.dom.message.WSSecHeader;
59 import org.apache.wss4j.dom.message.WSSecSAMLToken;
60 import org.apache.wss4j.stax.ext.WSSConstants;
61 import org.apache.wss4j.stax.ext.WSSSecurityProperties;
62 import org.apache.wss4j.stax.setup.ConfigurationConverter;
63 import org.apache.wss4j.stax.setup.InboundWSSec;
64 import org.apache.wss4j.stax.setup.OutboundWSSec;
65 import org.apache.wss4j.stax.setup.WSSec;
66 import org.apache.wss4j.stax.test.AbstractTestBase;
67 import org.apache.wss4j.stax.test.utils.StAX2DOM;
68 import org.apache.wss4j.stax.test.utils.XmlReaderToWriter;
69 import org.apache.wss4j.stax.validate.SamlTokenValidatorImpl;
70 import org.apache.xml.security.encryption.EncryptedData;
71 import org.apache.xml.security.encryption.EncryptedKey;
72 import org.apache.xml.security.encryption.XMLCipher;
73 import org.apache.xml.security.exceptions.XMLSecurityException;
74 import org.apache.xml.security.keys.KeyInfo;
75 import org.apache.xml.security.stax.securityEvent.SecurityEvent;
76 import org.junit.jupiter.api.Test;
77 import org.opensaml.core.xml.XMLObjectBuilder;
78 import org.opensaml.core.xml.XMLObjectBuilderFactory;
79 import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
80 import org.opensaml.core.xml.schema.XSAny;
81 import org.opensaml.saml.common.SAMLObjectBuilder;
82 import org.opensaml.saml.saml2.core.AttributeValue;
83 import org.opensaml.saml.saml2.core.Conditions;
84 import org.w3c.dom.Document;
85 import org.w3c.dom.Element;
86 import org.w3c.dom.NodeList;
87
88 import static org.junit.jupiter.api.Assertions.assertTrue;
89 import static org.junit.jupiter.api.Assertions.fail;
90 import static org.junit.jupiter.api.Assertions.assertEquals;
91
92 public class SAMLTokenTest extends AbstractTestBase {
93
94 private static final String IP_ADDRESS = "12.34.56.78";
95
96 @Test
97 public void testSAML1AuthnAssertionOutbound() throws Exception {
98
99 ByteArrayOutputStream baos = new ByteArrayOutputStream();
100 {
101 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
102 List<WSSConstants.Action> actions = new ArrayList<>();
103 actions.add(WSSConstants.SAML_TOKEN_UNSIGNED);
104 securityProperties.setActions(actions);
105 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
106 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
107 callbackHandler.setIssuer("www.example.com");
108 callbackHandler.setSignAssertion(false);
109 securityProperties.setSamlCallbackHandler(callbackHandler);
110
111 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
112 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
113 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
114 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
115 xmlStreamWriter.close();
116
117 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
118 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
119 assertEquals(nodeList.getLength(), 0);
120 }
121
122
123 {
124 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
125 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
126 }
127 }
128
129 @Test
130 public void testSAML1AuthnAssertionInbound() throws Exception {
131
132 ByteArrayOutputStream baos = new ByteArrayOutputStream();
133 {
134 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
135 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
136 callbackHandler.setIssuer("www.example.com");
137 callbackHandler.setSignAssertion(false);
138
139 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
140 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
141 Properties properties = new Properties();
142 properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
143 properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:1.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
144 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
145
146
147 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
148 assertEquals(nodeList.getLength(), 1);
149
150 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
151 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
152 }
153
154
155 {
156 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
157 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
158 securityProperties.setSamlCallbackHandler(new SAMLCallbackHandlerImpl());
159 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
160 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
161
162 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
163
164
165 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
166 assertEquals(nodeList.getLength(), 1);
167 }
168 }
169
170 @Test
171 public void testSAML1AttrAssertionOutbound() throws Exception {
172
173 ByteArrayOutputStream baos = new ByteArrayOutputStream();
174 {
175 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
176 List<WSSConstants.Action> actions = new ArrayList<>();
177 actions.add(WSSConstants.SAML_TOKEN_UNSIGNED);
178 securityProperties.setActions(actions);
179 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
180 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.ATTR);
181 callbackHandler.setIssuer("www.example.com");
182 callbackHandler.setSignAssertion(false);
183 securityProperties.setSamlCallbackHandler(callbackHandler);
184
185 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
186 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
187 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
188 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
189 xmlStreamWriter.close();
190
191 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
192 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
193 assertEquals(nodeList.getLength(), 0);
194 }
195
196
197 {
198 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
199 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
200 }
201 }
202
203 @Test
204 public void testSAML1AttrAssertionInbound() throws Exception {
205
206 ByteArrayOutputStream baos = new ByteArrayOutputStream();
207 {
208 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
209 callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
210 callbackHandler.setIssuer("www.example.com");
211 callbackHandler.setSignAssertion(false);
212
213 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
214 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
215 Properties properties = new Properties();
216 properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
217 properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:1.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
218 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
219
220
221 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
222 assertEquals(nodeList.getLength(), 1);
223
224 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
225 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
226 }
227
228
229 {
230 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
231 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
232 securityProperties.setSamlCallbackHandler(new SAMLCallbackHandlerImpl());
233 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
234 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
235
236 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
237
238
239 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
240 assertEquals(nodeList.getLength(), 1);
241 }
242 }
243
244 @Test
245 public void testSAML1AuthzAssertionOutbound() throws Exception {
246
247 ByteArrayOutputStream baos = new ByteArrayOutputStream();
248 {
249 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
250 List<WSSConstants.Action> actions = new ArrayList<>();
251 actions.add(WSSConstants.SAML_TOKEN_UNSIGNED);
252 securityProperties.setActions(actions);
253 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
254 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHZ);
255 callbackHandler.setIssuer("www.example.com");
256 callbackHandler.setSignAssertion(false);
257 callbackHandler.setResource("http://resource.org");
258 securityProperties.setSamlCallbackHandler(callbackHandler);
259
260 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
261 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
262 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
263 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
264 xmlStreamWriter.close();
265
266 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
267 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
268 assertEquals(nodeList.getLength(), 0);
269 }
270
271
272 {
273 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
274 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
275 }
276 }
277
278 @Test
279 public void testSAML1AuthzAssertionInbound() throws Exception {
280
281 ByteArrayOutputStream baos = new ByteArrayOutputStream();
282 {
283 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
284 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHZ);
285 callbackHandler.setIssuer("www.example.com");
286 callbackHandler.setResource("http://resource.org");
287 callbackHandler.setSignAssertion(false);
288
289 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
290 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
291 Properties properties = new Properties();
292 properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
293 properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:1.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
294 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
295
296
297 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
298 assertEquals(nodeList.getLength(), 1);
299
300 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
301 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
302 }
303
304
305 {
306 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
307 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
308 securityProperties.setSamlCallbackHandler(new SAMLCallbackHandlerImpl());
309 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
310 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
311
312 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
313
314
315 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
316 assertEquals(nodeList.getLength(), 1);
317 }
318 }
319
320 @Test
321 public void testSAML2AuthnAssertionOutbound() throws Exception {
322
323 ByteArrayOutputStream baos = new ByteArrayOutputStream();
324 {
325 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
326 List<WSSConstants.Action> actions = new ArrayList<>();
327 actions.add(WSSConstants.SAML_TOKEN_UNSIGNED);
328 securityProperties.setActions(actions);
329 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
330 callbackHandler.setSamlVersion(Version.SAML_20);
331 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
332 callbackHandler.setIssuer("www.example.com");
333 callbackHandler.setSignAssertion(false);
334 securityProperties.setSamlCallbackHandler(callbackHandler);
335
336 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
337 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
338 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
339 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
340 xmlStreamWriter.close();
341
342 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
343 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
344 assertEquals(nodeList.getLength(), 0);
345 }
346
347
348 {
349 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
350 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
351 }
352 }
353
354 @Test
355 public void testSAML2AuthnAssertionInbound() throws Exception {
356
357 ByteArrayOutputStream baos = new ByteArrayOutputStream();
358 {
359 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
360 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
361 callbackHandler.setIssuer("www.example.com");
362 callbackHandler.setSignAssertion(false);
363
364 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
365 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
366 Properties properties = new Properties();
367 properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
368 properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
369 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
370
371
372 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
373 assertEquals(nodeList.getLength(), 1);
374
375 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
376 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
377 }
378
379
380 {
381 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
382 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
383 securityProperties.setSamlCallbackHandler(new SAMLCallbackHandlerImpl());
384 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
385 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
386
387 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
388
389
390 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
391 assertEquals(nodeList.getLength(), 1);
392 }
393 }
394
395 @Test
396 public void testSAML2AttrAssertionOutbound() throws Exception {
397
398 ByteArrayOutputStream baos = new ByteArrayOutputStream();
399 {
400 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
401 List<WSSConstants.Action> actions = new ArrayList<>();
402 actions.add(WSSConstants.SAML_TOKEN_UNSIGNED);
403 securityProperties.setActions(actions);
404 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
405 callbackHandler.setSamlVersion(Version.SAML_20);
406 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.ATTR);
407 callbackHandler.setIssuer("www.example.com");
408 callbackHandler.setSignAssertion(false);
409 securityProperties.setSamlCallbackHandler(callbackHandler);
410
411 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
412 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
413 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
414 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
415 xmlStreamWriter.close();
416
417 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
418 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
419 assertEquals(nodeList.getLength(), 0);
420 }
421
422
423 {
424 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
425 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
426 }
427 }
428
429 @Test
430 public void testSAML2AttrAssertionInbound() throws Exception {
431
432 ByteArrayOutputStream baos = new ByteArrayOutputStream();
433 {
434 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
435 callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
436 callbackHandler.setIssuer("www.example.com");
437 callbackHandler.setSignAssertion(false);
438
439 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
440 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
441 Properties properties = new Properties();
442 properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
443 properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
444 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
445
446
447 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
448 assertEquals(nodeList.getLength(), 1);
449
450 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
451 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
452 }
453
454
455 {
456 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
457 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
458 securityProperties.setSamlCallbackHandler(new SAMLCallbackHandlerImpl());
459 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
460 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
461
462 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
463
464
465 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
466 assertEquals(nodeList.getLength(), 1);
467 }
468 }
469
470 @Test
471 public void testSAML2AuthzAssertionOutbound() throws Exception {
472
473 ByteArrayOutputStream baos = new ByteArrayOutputStream();
474 {
475 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
476 List<WSSConstants.Action> actions = new ArrayList<>();
477 actions.add(WSSConstants.SAML_TOKEN_UNSIGNED);
478 securityProperties.setActions(actions);
479 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
480 callbackHandler.setSamlVersion(Version.SAML_20);
481 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHZ);
482 callbackHandler.setIssuer("www.example.com");
483 callbackHandler.setSignAssertion(false);
484 callbackHandler.setResource("http://resource.org");
485 securityProperties.setSamlCallbackHandler(callbackHandler);
486
487 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
488 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
489 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
490 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
491 xmlStreamWriter.close();
492
493 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
494 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
495 assertEquals(nodeList.getLength(), 0);
496 }
497
498
499 {
500 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
501 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
502 }
503 }
504
505 @Test
506 public void testSAML2AuthzAssertionInbound() throws Exception {
507
508 ByteArrayOutputStream baos = new ByteArrayOutputStream();
509 {
510 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
511 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHZ);
512 callbackHandler.setIssuer("www.example.com");
513 callbackHandler.setResource("http://resource.org");
514 callbackHandler.setSignAssertion(false);
515
516 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
517 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
518 Properties properties = new Properties();
519 properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
520 properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
521 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
522
523
524 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
525 assertEquals(nodeList.getLength(), 1);
526
527 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
528 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
529 }
530
531
532 {
533 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
534 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
535 securityProperties.setSamlCallbackHandler(new SAMLCallbackHandlerImpl());
536 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
537 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
538
539 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
540
541
542 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
543 assertEquals(nodeList.getLength(), 1);
544 }
545 }
546
547
548
549
550
551 @Test
552 public void testSAML1SubjectNameIDFormatOutbound() throws Exception {
553
554 ByteArrayOutputStream baos = new ByteArrayOutputStream();
555 {
556 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
557 List<WSSConstants.Action> actions = new ArrayList<>();
558 actions.add(WSSConstants.SAML_TOKEN_UNSIGNED);
559 securityProperties.setActions(actions);
560 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
561 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
562 callbackHandler.setIssuer("www.example.com");
563 callbackHandler.setSignAssertion(false);
564 callbackHandler.setSubjectNameIDFormat(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS);
565 securityProperties.setSamlCallbackHandler(callbackHandler);
566
567 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
568 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
569 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
570 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
571 xmlStreamWriter.close();
572
573 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
574 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
575 assertEquals(nodeList.getLength(), 0);
576 }
577
578
579 {
580 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
581 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
582 }
583 }
584
585
586
587
588
589 @Test
590 public void testSAML2SubjectNameIDFormatOutbound() throws Exception {
591
592 ByteArrayOutputStream baos = new ByteArrayOutputStream();
593 {
594 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
595 List<WSSConstants.Action> actions = new ArrayList<>();
596 actions.add(WSSConstants.SAML_TOKEN_UNSIGNED);
597 securityProperties.setActions(actions);
598 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
599 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
600 callbackHandler.setSamlVersion(Version.SAML_20);
601 callbackHandler.setIssuer("www.example.com");
602 callbackHandler.setSignAssertion(false);
603 callbackHandler.setSubjectNameIDFormat(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS);
604 securityProperties.setSamlCallbackHandler(callbackHandler);
605
606 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
607 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
608 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
609 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
610 xmlStreamWriter.close();
611
612 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
613 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
614 assertEquals(nodeList.getLength(), 0);
615 }
616
617
618 {
619 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
620 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
621 }
622 }
623
624
625
626
627
628 @Test
629 public void testSAML1SubjectLocalityOutbound() throws Exception {
630
631 ByteArrayOutputStream baos = new ByteArrayOutputStream();
632 {
633 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
634 List<WSSConstants.Action> actions = new ArrayList<>();
635 actions.add(WSSConstants.SAML_TOKEN_UNSIGNED);
636 securityProperties.setActions(actions);
637 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
638 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
639 callbackHandler.setIssuer("www.example.com");
640 callbackHandler.setSignAssertion(false);
641 callbackHandler.setSubjectLocality(IP_ADDRESS, "test-dns");
642 securityProperties.setSamlCallbackHandler(callbackHandler);
643
644 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
645 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
646 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
647 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
648 xmlStreamWriter.close();
649
650 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
651 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
652 assertEquals(nodeList.getLength(), 0);
653 }
654
655
656 {
657 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
658 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
659 }
660 }
661
662
663
664
665
666 @Test
667 public void testSAML2SubjectLocalityOutbound() throws Exception {
668
669 ByteArrayOutputStream baos = new ByteArrayOutputStream();
670 {
671 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
672 List<WSSConstants.Action> actions = new ArrayList<>();
673 actions.add(WSSConstants.SAML_TOKEN_UNSIGNED);
674 securityProperties.setActions(actions);
675 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
676 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
677 callbackHandler.setIssuer("www.example.com");
678 callbackHandler.setSignAssertion(false);
679 callbackHandler.setSamlVersion(Version.SAML_20);
680 callbackHandler.setSubjectLocality(IP_ADDRESS, "test-dns");
681 securityProperties.setSamlCallbackHandler(callbackHandler);
682
683 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
684 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
685 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
686 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
687 xmlStreamWriter.close();
688
689 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
690 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
691 assertEquals(nodeList.getLength(), 0);
692 }
693
694
695 {
696 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
697 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
698 }
699 }
700
701
702
703
704
705 @Test
706 public void testSAML1ResourceOutbound() throws Exception {
707
708 ByteArrayOutputStream baos = new ByteArrayOutputStream();
709 {
710 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
711 List<WSSConstants.Action> actions = new ArrayList<>();
712 actions.add(WSSConstants.SAML_TOKEN_UNSIGNED);
713 securityProperties.setActions(actions);
714 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
715 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHZ);
716 callbackHandler.setIssuer("www.example.com");
717 callbackHandler.setResource("http://resource.org");
718 callbackHandler.setSignAssertion(false);
719 securityProperties.setSamlCallbackHandler(callbackHandler);
720
721 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
722 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
723 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
724 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
725 xmlStreamWriter.close();
726
727 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
728 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
729 assertEquals(nodeList.getLength(), 0);
730 }
731
732
733 {
734 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
735 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
736 }
737 }
738
739
740
741
742
743
744 @Test
745 @SuppressWarnings("unchecked")
746 public void testSAML2AttrAssertionCustomAttributeOutbound() throws Exception {
747
748 ByteArrayOutputStream baos = new ByteArrayOutputStream();
749 {
750 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
751 List<WSSConstants.Action> actions = new ArrayList<>();
752 actions.add(WSSConstants.SAML_TOKEN_UNSIGNED);
753 securityProperties.setActions(actions);
754 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
755 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.ATTR);
756 callbackHandler.setIssuer("www.example.com");
757 callbackHandler.setSignAssertion(false);
758 callbackHandler.setSamlVersion(Version.SAML_20);
759
760
761 XMLObjectBuilderFactory builderFactory = XMLObjectProviderRegistrySupport.getBuilderFactory();
762
763 SAMLObjectBuilder<Conditions> conditionsV2Builder =
764 (SAMLObjectBuilder<Conditions>) builderFactory.getBuilder(Conditions.DEFAULT_ELEMENT_NAME);
765 Conditions conditions = conditionsV2Builder.buildObject();
766 Instant newNotBefore = Instant.now();
767 conditions.setNotBefore(newNotBefore);
768 conditions.setNotOnOrAfter(newNotBefore.plus(Duration.ofMinutes(5)));
769
770 XMLObjectBuilder<XSAny> xsAnyBuilder =
771 (XMLObjectBuilder<XSAny>)builderFactory.getBuilder(XSAny.TYPE_NAME);
772 XSAny attributeValue = xsAnyBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME);
773 attributeValue.getUnknownXMLObjects().add(conditions);
774
775 List<Object> attributeValues = new ArrayList<>();
776 attributeValues.add(attributeValue);
777 callbackHandler.setCustomAttributeValues(attributeValues);
778
779 securityProperties.setSamlCallbackHandler(callbackHandler);
780
781 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
782 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
783 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
784 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
785 xmlStreamWriter.close();
786
787 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
788 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
789 assertEquals(nodeList.getLength(), 0);
790 }
791
792
793 {
794 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
795 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
796 }
797 }
798
799 @Test
800 public void testSAML1AuthnAssertionPropertiesOutbound() throws Exception {
801
802 ByteArrayOutputStream baos = new ByteArrayOutputStream();
803 {
804 Map<String, Object> config = new HashMap<>();
805 config.put(ConfigurationConstants.ACTION, ConfigurationConstants.SAML_TOKEN_UNSIGNED);
806
807 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
808 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
809 callbackHandler.setIssuer("www.example.com");
810 callbackHandler.setSignAssertion(false);
811 config.put(ConfigurationConstants.SAML_CALLBACK_REF, callbackHandler);
812
813 WSSSecurityProperties securityProperties = ConfigurationConverter.convert(config);
814 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
815 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
816 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
817 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
818 xmlStreamWriter.close();
819
820 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
821 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
822 assertEquals(nodeList.getLength(), 0);
823 }
824
825
826 {
827 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
828 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
829 }
830 }
831
832 @Test
833 public void testSAML1AuthnAssertionPropertiesInbound() throws Exception {
834
835 ByteArrayOutputStream baos = new ByteArrayOutputStream();
836 {
837 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
838 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
839 callbackHandler.setIssuer("www.example.com");
840 callbackHandler.setSignAssertion(false);
841
842 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
843 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
844 Properties properties = new Properties();
845 properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
846 properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:1.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
847 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
848
849
850 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
851 assertEquals(nodeList.getLength(), 1);
852
853 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
854 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
855 }
856
857
858 {
859 Map<String, Object> config = new HashMap<>();
860 config.put(ConfigurationConstants.ACTION, ConfigurationConstants.SAML_TOKEN_UNSIGNED);
861 config.put(ConfigurationConstants.SIG_VER_PROP_FILE, "receiver-crypto.properties");
862
863 WSSSecurityProperties securityProperties = ConfigurationConverter.convert(config);
864 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
865 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
866
867 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
868
869
870 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
871 assertEquals(nodeList.getLength(), 1);
872 }
873 }
874
875
876
877
878
879 @Test
880 public void testSAML2EncryptedAssertion() throws Exception {
881
882 ByteArrayOutputStream baos = new ByteArrayOutputStream();
883 Crypto crypto = CryptoFactory.getInstance("wss40.properties");
884 {
885 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
886
887 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
888 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
889 callbackHandler.setIssuer("www.example.com");
890
891 SAMLCallback samlCallback = new SAMLCallback();
892 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
893 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
894
895 Document doc = SOAPUtil.toSOAPPart(sourceDocument);
896 WSSecHeader secHeader = new WSSecHeader(doc);
897 secHeader.insertSecurityHeader();
898
899 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
900
901 wsSign.prepare(samlAssertion);
902
903
904 Element assertionElement = wsSign.getElement();
905 Element encryptedAssertionElement =
906 doc.createElementNS(WSConstants.SAML2_NS, WSConstants.ENCRYPED_ASSERTION_LN);
907 encryptedAssertionElement.appendChild(assertionElement);
908 secHeader.getSecurityHeaderElement().appendChild(encryptedAssertionElement);
909
910
911 KeyGenerator keygen = KeyGenerator.getInstance("AES");
912 keygen.init(128);
913 SecretKey secretKey = keygen.generateKey();
914 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
915 cryptoType.setAlias("wss40");
916 X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
917 assertTrue(certs != null && certs.length > 0 && certs[0] != null);
918
919 encryptElement(doc, assertionElement, WSConstants.AES_128, secretKey,
920 WSConstants.KEYTRANSPORT_RSAOAEP, certs[0], false);
921
922 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
923 transformer.transform(new DOMSource(doc), new StreamResult(baos));
924 }
925
926 {
927 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
928 securityProperties.setDecryptionCrypto(crypto);
929 securityProperties.setCallbackHandler(new KeystoreCallbackHandler());
930 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
931 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
932
933 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
934
935
936 NodeList nodeList =
937 document.getElementsByTagNameNS(WSSConstants.TAG_SAML2_ASSERTION.getNamespaceURI(), WSSConstants.TAG_SAML2_ASSERTION.getLocalPart());
938 assertEquals(nodeList.getLength(), 1);
939 }
940 }
941
942 @Test
943 public void testRequiredSubjectConfirmationMethod() throws Exception {
944
945 ByteArrayOutputStream baos = new ByteArrayOutputStream();
946 {
947 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
948 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
949 callbackHandler.setIssuer("www.example.com");
950 callbackHandler.setSignAssertion(false);
951
952 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
953 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
954 Properties properties = new Properties();
955 properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
956 properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
957 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
958
959
960 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
961 assertEquals(nodeList.getLength(), 1);
962
963 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
964 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
965 }
966
967
968 {
969 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
970 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
971 securityProperties.setSamlCallbackHandler(new SAMLCallbackHandlerImpl());
972
973 SamlTokenValidatorImpl validator = new SamlTokenValidatorImpl();
974 validator.setRequiredSubjectConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
975 securityProperties.addValidator(WSSConstants.TAG_SAML2_ASSERTION, validator);
976 securityProperties.addValidator(WSSConstants.TAG_SAML_ASSERTION, validator);
977
978 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
979 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
980
981 Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
982
983
984 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
985 assertEquals(nodeList.getLength(), 1);
986 }
987
988 baos = new ByteArrayOutputStream();
989
990 {
991 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
992 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
993 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
994 callbackHandler.setIssuer("www.example.com");
995 callbackHandler.setSignAssertion(false);
996
997 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
998 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
999 Properties properties = new Properties();
1000 properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
1001 properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
1002 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
1003
1004
1005 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
1006 assertEquals(nodeList.getLength(), 1);
1007
1008 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1009 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1010 }
1011
1012
1013 {
1014 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1015 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1016 securityProperties.setSamlCallbackHandler(new SAMLCallbackHandlerImpl());
1017
1018 SamlTokenValidatorImpl validator = new SamlTokenValidatorImpl();
1019 validator.setRequiredSubjectConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
1020 securityProperties.addValidator(WSSConstants.TAG_SAML2_ASSERTION, validator);
1021 securityProperties.addValidator(WSSConstants.TAG_SAML_ASSERTION, validator);
1022
1023 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
1024 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1025
1026 try {
1027 StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
1028 fail("Failure expected on a Bearer assertion");
1029 } catch (XMLStreamException e) {
1030 assertTrue(e.getCause() instanceof XMLSecurityException);
1031 }
1032 }
1033 }
1034
1035 @Test
1036 public void testStandardSubjectConfirmationMethod() throws Exception {
1037
1038 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1039 {
1040 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1041 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1042 callbackHandler.setIssuer("www.example.com");
1043 callbackHandler.setConfirmationMethod("urn:oasis:names:tc:SAML:2.0:cm:custom");
1044 callbackHandler.setSignAssertion(false);
1045
1046 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1047 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
1048 Properties properties = new Properties();
1049 properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
1050 properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
1051 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
1052
1053
1054 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
1055 assertEquals(nodeList.getLength(), 1);
1056
1057 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1058 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1059 }
1060
1061
1062 {
1063 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1064 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1065 securityProperties.setSamlCallbackHandler(new SAMLCallbackHandlerImpl());
1066
1067 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
1068 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1069
1070 try {
1071 StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
1072 fail("Failure expected on an unknown subject confirmation method");
1073 } catch (XMLStreamException e) {
1074 assertTrue(e.getCause() instanceof XMLSecurityException);
1075 }
1076 }
1077
1078
1079 {
1080 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1081 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1082 securityProperties.setSamlCallbackHandler(new SAMLCallbackHandlerImpl());
1083
1084 SamlTokenValidatorImpl validator = new SamlTokenValidatorImpl();
1085 validator.setRequireStandardSubjectConfirmationMethod(false);
1086 securityProperties.addValidator(WSSConstants.TAG_SAML2_ASSERTION, validator);
1087 securityProperties.addValidator(WSSConstants.TAG_SAML_ASSERTION, validator);
1088
1089 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
1090 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1091
1092 StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
1093 }
1094 }
1095
1096 @Test
1097 public void testUnsignedBearer() throws Exception {
1098
1099 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1100 {
1101 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
1102 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
1103 callbackHandler.setIssuer("www.example.com");
1104 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
1105 callbackHandler.setSignAssertion(false);
1106
1107 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
1108 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
1109 Properties properties = new Properties();
1110 properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
1111 properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
1112 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
1113
1114
1115 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
1116 assertEquals(nodeList.getLength(), 1);
1117
1118 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
1119 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
1120 }
1121
1122
1123 {
1124 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1125 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1126 securityProperties.setSamlCallbackHandler(new SAMLCallbackHandlerImpl());
1127
1128 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
1129 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1130
1131 try {
1132 StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
1133 fail("Failure expected on an unsigned bearer token");
1134 } catch (XMLStreamException e) {
1135 assertTrue(e.getCause() instanceof XMLSecurityException);
1136 }
1137 }
1138
1139
1140 {
1141 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1142 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
1143 securityProperties.setSamlCallbackHandler(new SAMLCallbackHandlerImpl());
1144
1145 SamlTokenValidatorImpl validator = new SamlTokenValidatorImpl();
1146 validator.setRequireBearerSignature(false);
1147 securityProperties.addValidator(WSSConstants.TAG_SAML2_ASSERTION, validator);
1148 securityProperties.addValidator(WSSConstants.TAG_SAML_ASSERTION, validator);
1149
1150 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
1151 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
1152
1153 StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
1154 }
1155 }
1156
1157 @Test
1158 public void testSAML2IssuerFormatOutbound() throws Exception {
1159
1160 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1161 {
1162 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
1163 List<WSSConstants.Action> actions = new ArrayList<>();
1164 actions.add(WSSConstants.SAML_TOKEN_UNSIGNED);
1165 securityProperties.setActions(actions);
1166 SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
1167 callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
1168 callbackHandler.setIssuer("www.example.com");
1169 callbackHandler.setSignAssertion(false);
1170 callbackHandler.setIssuerFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent");
1171 securityProperties.setSamlCallbackHandler(callbackHandler);
1172
1173 OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
1174 XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
1175 XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
1176 XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
1177 xmlStreamWriter.close();
1178
1179 Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
1180 NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
1181 assertEquals(nodeList.getLength(), 0);
1182 }
1183
1184
1185 {
1186 String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
1187 doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
1188 }
1189 }
1190
1191 private void encryptElement(
1192 Document document,
1193 Element elementToEncrypt,
1194 String algorithm,
1195 Key encryptingKey,
1196 String keyTransportAlgorithm,
1197 X509Certificate wrappingCert,
1198 boolean content
1199 ) throws Exception {
1200 XMLCipher cipher = XMLCipher.getInstance(algorithm);
1201 cipher.init(XMLCipher.ENCRYPT_MODE, encryptingKey);
1202
1203 if (wrappingCert != null) {
1204 XMLCipher newCipher = XMLCipher.getInstance(keyTransportAlgorithm);
1205 newCipher.init(XMLCipher.WRAP_MODE, wrappingCert.getPublicKey());
1206
1207 EncryptedKey encryptedKey = newCipher.encryptKey(document, encryptingKey);
1208
1209 KeyInfo encryptedKeyKeyInfo = encryptedKey.getKeyInfo();
1210 if (encryptedKeyKeyInfo == null) {
1211 encryptedKeyKeyInfo = new KeyInfo(document);
1212 encryptedKeyKeyInfo.getElement().setAttributeNS(
1213 "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
1214 );
1215 encryptedKey.setKeyInfo(encryptedKeyKeyInfo);
1216 }
1217
1218 SecurityTokenReference securityTokenReference = new SecurityTokenReference(document);
1219 securityTokenReference.addWSSENamespace();
1220 securityTokenReference.setKeyIdentifierSKI(wrappingCert, null);
1221 encryptedKeyKeyInfo.addUnknownElement(securityTokenReference.getElement());
1222
1223
1224 EncryptedData builder = cipher.getEncryptedData();
1225 KeyInfo builderKeyInfo = builder.getKeyInfo();
1226 if (builderKeyInfo == null) {
1227 builderKeyInfo = new KeyInfo(document);
1228 builderKeyInfo.getElement().setAttributeNS(
1229 "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
1230 );
1231 builder.setKeyInfo(builderKeyInfo);
1232 }
1233
1234 builderKeyInfo.add(encryptedKey);
1235 }
1236
1237 cipher.doFinal(document, elementToEncrypt, content);
1238 }
1239 }