View Javadoc
1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
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.util.ArrayList;
26  import java.util.List;
27  import java.util.Properties;
28  
29  import javax.xml.stream.XMLStreamReader;
30  import javax.xml.stream.XMLStreamWriter;
31  import javax.xml.transform.dom.DOMSource;
32  import javax.xml.transform.stream.StreamResult;
33  
34  import org.apache.wss4j.common.crypto.CryptoType;
35  import org.apache.wss4j.common.saml.bean.Version;
36  import org.apache.wss4j.common.saml.builder.SAML1Constants;
37  import org.apache.wss4j.common.saml.builder.SAML2Constants;
38  import org.apache.wss4j.dom.handler.WSHandlerConstants;
39  import org.apache.wss4j.stax.ext.WSSConstants;
40  import org.apache.wss4j.stax.ext.WSSSecurityProperties;
41  import org.apache.wss4j.stax.impl.securityToken.HttpsSecurityTokenImpl;
42  import org.apache.wss4j.stax.securityEvent.HttpsTokenSecurityEvent;
43  import org.apache.wss4j.stax.securityToken.HttpsSecurityToken;
44  import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
45  import org.apache.wss4j.stax.setup.InboundWSSec;
46  import org.apache.wss4j.stax.setup.OutboundWSSec;
47  import org.apache.wss4j.stax.setup.WSSec;
48  import org.apache.wss4j.stax.test.AbstractTestBase;
49  import org.apache.wss4j.stax.test.CallbackHandlerImpl;
50  import org.apache.wss4j.stax.test.utils.StAX2DOM;
51  import org.apache.wss4j.stax.test.utils.XmlReaderToWriter;
52  import org.apache.wss4j.stax.utils.WSSUtils;
53  import org.apache.xml.security.stax.securityEvent.SecurityEvent;
54  import org.junit.jupiter.api.Test;
55  import org.w3c.dom.Document;
56  import org.w3c.dom.Element;
57  import org.w3c.dom.NodeList;
58  
59  import static org.junit.jupiter.api.Assertions.assertEquals;
60  import static org.junit.jupiter.api.Assertions.assertNotNull;
61  import static org.junit.jupiter.api.Assertions.assertTrue;
62  
63  public class SAMLTokenSVTest extends AbstractTestBase {
64  
65      @Test
66      public void testSAML1AuthnAssertionOutbound() throws Exception {
67  
68          ByteArrayOutputStream baos = new ByteArrayOutputStream();
69          {
70              WSSSecurityProperties securityProperties = new WSSSecurityProperties();
71              List<WSSConstants.Action> actions = new ArrayList<>();
72              actions.add(WSSConstants.SAML_TOKEN_SIGNED);
73              securityProperties.setActions(actions);
74              SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
75              callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
76              callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
77              callbackHandler.setIssuer("www.example.com");
78              callbackHandler.setSignAssertion(false);
79              securityProperties.setSamlCallbackHandler(callbackHandler);
80              securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
81              securityProperties.setSignatureUser("transmitter");
82              securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
83              securityProperties.setCallbackHandler(new CallbackHandlerImpl());
84  
85              OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
86              XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
87              XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
88              XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
89              xmlStreamWriter.close();
90  
91              Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
92              NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
93              assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
94  
95              nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Reference.getNamespaceURI(), WSSConstants.TAG_dsig_Reference.getLocalPart());
96              assertEquals(nodeList.getLength(), 2);
97  
98              nodeList = document.getElementsByTagNameNS(WSSConstants.NS_SOAP11, WSSConstants.TAG_SOAP_BODY_LN);
99              assertEquals(nodeList.getLength(), 1);
100             String idAttrValue = ((Element) nodeList.item(0)).getAttributeNS(WSSConstants.ATT_WSU_ID.getNamespaceURI(), WSSConstants.ATT_WSU_ID.getLocalPart());
101             assertNotNull(idAttrValue);
102             assertTrue(idAttrValue.length() > 0);
103         }
104 
105         //done signature; now test sig-verification:
106         {
107             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.SAML_TOKEN_UNSIGNED;
108             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
109         }
110     }
111 
112     @Test
113     public void testSAML1AuthnAssertionInbound() throws Exception {
114 
115         ByteArrayOutputStream baos = new ByteArrayOutputStream();
116         {
117             SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
118             callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
119             callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
120             callbackHandler.setIssuer("www.example.com");
121             callbackHandler.setSignAssertion(false);
122 
123             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
124             String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
125             Properties properties = new Properties();
126             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
127             properties.setProperty(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
128             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
129 
130             //some test that we can really sure we get what we want from WSS4J
131             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
132             assertEquals(nodeList.getLength(), 1);
133 
134             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
135             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
136         }
137 
138         //done signature; now test sig-verification:
139         {
140             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
141             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
142             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
143             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
144 
145             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
146 
147             //header element must still be there
148             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
149             assertEquals(nodeList.getLength(), 1);
150         }
151     }
152 
153     @Test
154     public void testSAML1AuthnAssertionSignedOutbound() throws Exception {
155 
156         ByteArrayOutputStream baos = new ByteArrayOutputStream();
157         {
158             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
159             List<WSSConstants.Action> actions = new ArrayList<>();
160             actions.add(WSSConstants.SAML_TOKEN_SIGNED);
161             securityProperties.setActions(actions);
162             SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
163             callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
164             callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
165             callbackHandler.setIssuer("www.example.com");
166             securityProperties.setSamlCallbackHandler(callbackHandler);
167             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
168             securityProperties.setSignatureUser("transmitter");
169             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_X509KeyIdentifier);
170             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
171 
172             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
173             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
174             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
175             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
176             xmlStreamWriter.close();
177 
178             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
179             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
180             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
181             assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
182 
183             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Reference.getNamespaceURI(), WSSConstants.TAG_dsig_Reference.getLocalPart());
184             assertEquals(nodeList.getLength(), 3);
185             String referenceId = ((Element) nodeList.item(1)).getAttributeNode(WSSConstants.ATT_NULL_URI.getLocalPart()).getValue();
186             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_WSSE_SECURITY_TOKEN_REFERENCE.getNamespaceURI(), WSSConstants.TAG_WSSE_SECURITY_TOKEN_REFERENCE.getLocalPart());
187             assertEquals(nodeList.getLength(), 2);
188             String tokenId = ((Element) nodeList.item(0)).getAttributeNodeNS(WSSConstants.ATT_WSU_ID.getNamespaceURI(), WSSConstants.ATT_WSU_ID.getLocalPart()).getValue();
189             assertEquals(tokenId, WSSUtils.dropReferenceMarker(referenceId));
190 
191             nodeList = document.getElementsByTagNameNS(WSSConstants.NS_SOAP11, WSSConstants.TAG_SOAP_BODY_LN);
192             assertEquals(nodeList.getLength(), 1);
193             String idAttrValue = ((Element) nodeList.item(0)).getAttributeNS(WSSConstants.ATT_WSU_ID.getNamespaceURI(), WSSConstants.ATT_WSU_ID.getLocalPart());
194             assertNotNull(idAttrValue);
195             assertTrue(idAttrValue.length() > 0);
196         }
197 
198         //done signature; now test sig-verification:
199         {
200             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.SAML_TOKEN_SIGNED;
201             Properties properties = new Properties();
202             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
203         }
204     }
205 
206     @Test
207     public void testSAML1AuthnAssertionSignedInbound() throws Exception {
208 
209         ByteArrayOutputStream baos = new ByteArrayOutputStream();
210         {
211             SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
212             callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
213             callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
214             callbackHandler.setIssuer("www.example.com");
215 
216             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
217             String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
218             Properties properties = new Properties();
219             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
220             properties.setProperty(WSHandlerConstants.SIG_KEY_ID, "X509KeyIdentifier");
221             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
222 
223             //some test that we can really sure we get what we want from WSS4J
224             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
225             assertEquals(nodeList.getLength(), 2);
226 
227             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
228             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
229         }
230 
231         //done signature; now test sig-verification:
232         {
233             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
234             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
235             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
236             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
237 
238             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
239 
240             //header element must still be there
241             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
242             assertEquals(nodeList.getLength(), 2);
243         }
244     }
245 
246     @Test
247     public void testSAML1AttrAssertionOutbound() throws Exception {
248 
249         ByteArrayOutputStream baos = new ByteArrayOutputStream();
250         {
251             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
252             List<WSSConstants.Action> actions = new ArrayList<>();
253             actions.add(WSSConstants.SAML_TOKEN_SIGNED);
254             securityProperties.setActions(actions);
255             SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
256             callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.ATTR);
257             callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
258             callbackHandler.setIssuer("www.example.com");
259             callbackHandler.setSignAssertion(false);
260             securityProperties.setSamlCallbackHandler(callbackHandler);
261             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
262             securityProperties.setSignatureUser("transmitter");
263             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
264             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
265 
266             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
267             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
268             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
269             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
270             xmlStreamWriter.close();
271 
272             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
273             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
274             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
275 
276             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Reference.getNamespaceURI(), WSSConstants.TAG_dsig_Reference.getLocalPart());
277             assertEquals(nodeList.getLength(), 2);
278 
279             nodeList = document.getElementsByTagNameNS(WSSConstants.NS_SOAP11, WSSConstants.TAG_SOAP_BODY_LN);
280             assertEquals(nodeList.getLength(), 1);
281             String idAttrValue = ((Element) nodeList.item(0)).getAttributeNS(WSSConstants.ATT_WSU_ID.getNamespaceURI(), WSSConstants.ATT_WSU_ID.getLocalPart());
282             assertNotNull(idAttrValue);
283             assertTrue(idAttrValue.length() > 0);
284         }
285 
286         //done signature; now test sig-verification:
287         {
288             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.SAML_TOKEN_UNSIGNED;
289             doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
290         }
291     }
292 
293     @Test
294     public void testSAML1AttrAssertionInbound() throws Exception {
295 
296         ByteArrayOutputStream baos = new ByteArrayOutputStream();
297         {
298             SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
299             callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
300             callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
301             callbackHandler.setIssuer("www.example.com");
302             callbackHandler.setSignAssertion(false);
303 
304             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
305             String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
306             Properties properties = new Properties();
307             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
308             properties.setProperty(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
309             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
310 
311             //some test that we can really sure we get what we want from WSS4J
312             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
313             assertEquals(nodeList.getLength(), 1);
314 
315             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
316             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
317         }
318 
319         //done signature; now test sig-verification:
320         {
321             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
322             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
323             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
324             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
325 
326             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
327 
328             //header element must still be there
329             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
330             assertEquals(nodeList.getLength(), 1);
331         }
332     }
333 
334     @Test
335     public void testSAMLAssertionSVTransportSecurityInbound() throws Exception {
336 
337         ByteArrayOutputStream baos = new ByteArrayOutputStream();
338         {
339             SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
340             callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHZ);
341             callbackHandler.setIssuer("www.example.com");
342             callbackHandler.setResource("http://resource.org");
343             callbackHandler.setSignAssertion(false);
344 
345             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
346             String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
347             Properties properties = new Properties();
348             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
349             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
350 
351             //some test that we can really sure we get what we want from WSS4J
352             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
353             assertEquals(nodeList.getLength(), 0);
354 
355             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
356             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
357         }
358 
359         //done signature; now test sig-verification:
360         {
361             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
362             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
363             securityProperties.setCallbackHandler(new SAMLCallbackHandlerImpl());
364             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
365 
366             HttpsTokenSecurityEvent httpsTokenSecurityEvent = new HttpsTokenSecurityEvent();
367             httpsTokenSecurityEvent.setAuthenticationType(HttpsTokenSecurityEvent.AuthenticationType.HttpsClientCertificateAuthentication);
368             CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
369             cryptoType.setAlias("transmitter");
370             HttpsSecurityToken httpsSecurityToken = new HttpsSecurityTokenImpl(
371                     securityProperties.getSignatureVerificationCrypto().getX509Certificates(cryptoType)[0]);
372             httpsTokenSecurityEvent.setSecurityToken(httpsSecurityToken);
373 
374             List<SecurityEvent> requestSecurityEvents = new ArrayList<>();
375             requestSecurityEvents.add(httpsTokenSecurityEvent);
376 
377             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(
378                     xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())),
379                     requestSecurityEvents);
380 
381             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
382 
383             //header element must still be there
384             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
385             assertEquals(nodeList.getLength(), 0);
386         }
387     }
388 
389     @Test
390     public void testSAML2AuthnAssertionOutbound() throws Exception {
391 
392         ByteArrayOutputStream baos = new ByteArrayOutputStream();
393         {
394             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
395             List<WSSConstants.Action> actions = new ArrayList<>();
396             actions.add(WSSConstants.SAML_TOKEN_SIGNED);
397             securityProperties.setActions(actions);
398             SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
399             callbackHandler.setSamlVersion(Version.SAML_20);
400             callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.AUTHN);
401             callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
402             callbackHandler.setIssuer("www.example.com");
403             callbackHandler.setSignAssertion(false);
404             securityProperties.setSamlCallbackHandler(callbackHandler);
405             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
406             securityProperties.setSignatureUser("transmitter");
407             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
408             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
409 
410             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
411             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
412             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
413             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
414             xmlStreamWriter.close();
415 
416             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
417             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
418             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
419 
420             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Reference.getNamespaceURI(), WSSConstants.TAG_dsig_Reference.getLocalPart());
421             assertEquals(nodeList.getLength(), 2);
422 
423             nodeList = document.getElementsByTagNameNS(WSSConstants.NS_SOAP11, WSSConstants.TAG_SOAP_BODY_LN);
424             assertEquals(nodeList.getLength(), 1);
425             String idAttrValue = ((Element) nodeList.item(0)).getAttributeNS(WSSConstants.ATT_WSU_ID.getNamespaceURI(), WSSConstants.ATT_WSU_ID.getLocalPart());
426             assertNotNull(idAttrValue);
427             assertTrue(idAttrValue.length() > 0);
428         }
429 
430         //done signature; now test sig-verification:
431         {
432             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.SAML_TOKEN_UNSIGNED;
433             Properties properties = new Properties();
434             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
435         }
436     }
437 
438     @Test
439     public void testSAML2AuthnAssertionInbound() throws Exception {
440 
441         ByteArrayOutputStream baos = new ByteArrayOutputStream();
442         {
443             SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
444             callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
445             callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
446             callbackHandler.setIssuer("www.example.com");
447             callbackHandler.setSignAssertion(false);
448 
449             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
450             String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
451             Properties properties = new Properties();
452             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
453             properties.setProperty(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
454             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
455 
456             //some test that we can really sure we get what we want from WSS4J
457             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
458             assertEquals(nodeList.getLength(), 1);
459 
460             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
461             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
462         }
463 
464         //done signature; now test sig-verification:
465         {
466             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
467             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
468             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
469             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
470 
471             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
472 
473             //header element must still be there
474             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
475             assertEquals(nodeList.getLength(), 1);
476         }
477     }
478 
479     @Test
480     public void testSAML2AttrAssertionOutbound() throws Exception {
481 
482         ByteArrayOutputStream baos = new ByteArrayOutputStream();
483         {
484             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
485             List<WSSConstants.Action> actions = new ArrayList<>();
486             actions.add(WSSConstants.SAML_TOKEN_SIGNED);
487             securityProperties.setActions(actions);
488             SAMLCallbackHandlerImpl callbackHandler = new SAMLCallbackHandlerImpl();
489             callbackHandler.setSamlVersion(Version.SAML_20);
490             callbackHandler.setStatement(SAMLCallbackHandlerImpl.Statement.ATTR);
491             callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
492             callbackHandler.setIssuer("www.example.com");
493             callbackHandler.setSignAssertion(false);
494             securityProperties.setSamlCallbackHandler(callbackHandler);
495             securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
496             securityProperties.setSignatureUser("transmitter");
497             securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
498             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
499 
500             OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
501             XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
502             XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
503             XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
504             xmlStreamWriter.close();
505 
506             Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
507             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
508             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
509 
510             nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Reference.getNamespaceURI(), WSSConstants.TAG_dsig_Reference.getLocalPart());
511             assertEquals(nodeList.getLength(), 2);
512 
513             nodeList = document.getElementsByTagNameNS(WSSConstants.NS_SOAP11, WSSConstants.TAG_SOAP_BODY_LN);
514             assertEquals(nodeList.getLength(), 1);
515             String idAttrValue = ((Element) nodeList.item(0)).getAttributeNS(WSSConstants.ATT_WSU_ID.getNamespaceURI(), WSSConstants.ATT_WSU_ID.getLocalPart());
516             assertNotNull(idAttrValue);
517             assertTrue(idAttrValue.length() > 0);
518         }
519 
520         //done signature; now test sig-verification:
521         {
522             String action = WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.SAML_TOKEN_UNSIGNED;
523             Properties properties = new Properties();
524             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action, properties, false);
525         }
526     }
527 
528     @Test
529     public void testSAML2AttrAssertionInbound() throws Exception {
530 
531         ByteArrayOutputStream baos = new ByteArrayOutputStream();
532         {
533             SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
534             callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
535             callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
536             callbackHandler.setIssuer("www.example.com");
537             callbackHandler.setSignAssertion(false);
538 
539             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
540             String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
541             Properties properties = new Properties();
542             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
543             properties.setProperty(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
544             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
545 
546             //some test that we can really sure we get what we want from WSS4J
547             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
548             assertEquals(nodeList.getLength(), 1);
549 
550             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
551             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
552         }
553 
554         //done signature; now test sig-verification:
555         {
556             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
557             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
558             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
559             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
560 
561             Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
562 
563             //header element must still be there
564             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
565             assertEquals(nodeList.getLength(), 1);
566         }
567     }
568 }