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;
20  
21  import java.io.ByteArrayInputStream;
22  import java.io.ByteArrayOutputStream;
23  import java.io.InputStream;
24  import java.security.Principal;
25  import java.util.Properties;
26  
27  import javax.security.auth.x500.X500Principal;
28  import javax.xml.stream.XMLStreamReader;
29  import javax.xml.transform.dom.DOMSource;
30  import javax.xml.transform.stream.StreamResult;
31  
32  import org.apache.wss4j.common.bsp.BSPRule;
33  import org.apache.wss4j.common.principal.*;
34  import org.apache.wss4j.stax.securityToken.KeyValueSecurityToken;
35  import org.apache.wss4j.stax.securityToken.SamlSecurityToken;
36  import org.apache.wss4j.stax.securityToken.UsernameSecurityToken;
37  import org.apache.wss4j.stax.securityToken.X509SecurityToken;
38  import org.apache.wss4j.stax.setup.InboundWSSec;
39  import org.apache.wss4j.stax.setup.WSSec;
40  import org.apache.wss4j.stax.securityEvent.*;
41  import org.w3c.dom.Document;
42  import org.w3c.dom.Element;
43  import org.w3c.dom.NodeList;
44  import org.apache.wss4j.dom.handler.WSHandlerConstants;
45  import org.apache.wss4j.stax.ext.WSSConstants;
46  import org.apache.wss4j.stax.ext.WSSSecurityProperties;
47  import org.apache.wss4j.stax.test.saml.SAML1CallbackHandler;
48  import org.apache.wss4j.stax.test.utils.StAX2DOM;
49  import org.junit.jupiter.api.Test;
50  
51  import static org.junit.jupiter.api.Assertions.assertEquals;
52  import static org.junit.jupiter.api.Assertions.assertNotNull;
53  import static org.junit.jupiter.api.Assertions.assertTrue;
54  
55  /**
56   * A test for various Principals...
57   */
58  public class PrincipalTest extends AbstractTestBase {
59  
60      @Test
61      public void testUsernameToken() throws Exception {
62          ByteArrayOutputStream baos = new ByteArrayOutputStream();
63          {
64              InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
65              String action = WSHandlerConstants.USERNAME_TOKEN;
66              Properties properties = new Properties();
67              Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
68  
69              //some test that we can really sure we get what we want from WSS4J
70              NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_WSSE_USERNAME_TOKEN.getNamespaceURI(), WSSConstants.TAG_WSSE_USERNAME_TOKEN.getLocalPart());
71              assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
72  
73              nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_WSSE_PASSWORD.getNamespaceURI(), WSSConstants.TAG_WSSE_PASSWORD.getLocalPart());
74              assertEquals(nodeList.getLength(), 1);
75              assertEquals(((Element) nodeList.item(0)).getAttributeNS(null, WSSConstants.ATT_NULL_Type.getLocalPart()), WSSConstants.UsernameTokenPasswordType.PASSWORD_DIGEST.getNamespace());
76  
77              javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
78              transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
79          }
80  
81          //done UsernameToken; now verification:
82          {
83              WSSSecurityProperties securityProperties = new WSSSecurityProperties();
84              securityProperties.setCallbackHandler(new CallbackHandlerImpl());
85              //securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
86              InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
87  
88              WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
89                      WSSecurityEventConstants.USERNAME_TOKEN,
90                      WSSecurityEventConstants.OPERATION,
91              };
92              final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
93              XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
94  
95              StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
96  
97              // Check principal
98              UsernameTokenSecurityEvent event =
99                  (UsernameTokenSecurityEvent)securityEventListener.getSecurityEvent(WSSecurityEventConstants.USERNAME_TOKEN);
100             assertNotNull(event);
101             UsernameSecurityToken usernameSecurityToken = event.getSecurityToken();
102             Principal principal = usernameSecurityToken.getPrincipal();
103             assertTrue(principal instanceof UsernameTokenPrincipal);
104             UsernameTokenPrincipal usernameTokenPrincipal = (UsernameTokenPrincipal)principal;
105             assertTrue("transmitter".equals(usernameTokenPrincipal.getName()));
106             assertNotNull(usernameTokenPrincipal.getCreatedTime());
107             assertNotNull(usernameTokenPrincipal.getNonce());
108             assertNotNull(usernameTokenPrincipal.getPassword());
109             assertTrue(usernameTokenPrincipal.isPasswordDigest());
110             assertTrue(WSSConstants.NS_PASSWORD_DIGEST.equals(usernameTokenPrincipal.getPasswordType()));
111         }
112     }
113 
114     @Test
115     public void testSAMLToken() throws Exception {
116 
117         ByteArrayOutputStream baos = new ByteArrayOutputStream();
118         {
119             SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
120             callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
121             callbackHandler.setIssuer("www.example.com");
122             callbackHandler.setSignAssertion(false);
123 
124             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
125             String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
126             Properties properties = new Properties();
127             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
128             properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:1.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
129             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
130 
131             //some test that we can really sure we get what we want from WSS4J
132             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
133             assertEquals(nodeList.getLength(), 1);
134 
135             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
136             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
137         }
138 
139         //done signature; now test sig-verification:
140         {
141             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
142             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
143             securityProperties.setCallbackHandler(new CallbackHandlerImpl());
144             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
145 
146             WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
147                 WSSecurityEventConstants.SAML_TOKEN,
148                 WSSecurityEventConstants.OPERATION,
149             };
150             final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
151             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
152 
153             StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
154 
155             // Check principal
156             SamlTokenSecurityEvent event =
157                 (SamlTokenSecurityEvent)securityEventListener.getSecurityEvent(WSSecurityEventConstants.SAML_TOKEN);
158             assertNotNull(event);
159             SamlSecurityToken token = event.getSecurityToken();
160 
161             Principal principal = token.getPrincipal();
162             assertTrue(principal instanceof SAMLTokenPrincipal);
163             assertTrue(principal.getName().contains("uid=joe"));
164             assertNotNull(((SAMLTokenPrincipal)principal).getToken());
165         }
166     }
167 
168     @Test
169     public void testX509Certificate() throws Exception {
170 
171         ByteArrayOutputStream baos = new ByteArrayOutputStream();
172         {
173             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
174             String action = WSHandlerConstants.SIGNATURE;
175             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, new Properties());
176 
177             //some test that we can really sure we get what we want from WSS4J
178             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
179             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
180 
181             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
182             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
183         }
184 
185         //done signature; now test sig-verification:
186         {
187             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
188             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
189             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
190 
191             WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
192                 WSSecurityEventConstants.X509Token,
193                 WSSecurityEventConstants.OPERATION,
194             };
195             final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
196             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
197 
198             StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
199 
200             // Check principal
201             X509TokenSecurityEvent event =
202                 (X509TokenSecurityEvent)securityEventListener.getSecurityEvent(WSSecurityEventConstants.X509Token);
203             assertNotNull(event);
204             X509SecurityToken token = event.getSecurityToken();
205 
206             Principal principal = token.getPrincipal();
207             assertTrue(principal instanceof X500Principal);
208         }
209     }
210 
211     @Test
212     public void testRSAKeyValue() throws Exception {
213 
214         ByteArrayOutputStream baos = new ByteArrayOutputStream();
215         {
216             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
217             String action = WSHandlerConstants.SIGNATURE;
218             Properties properties = new Properties();
219             properties.put(WSHandlerConstants.SIG_KEY_ID, "KeyValue");
220             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
221 
222             //some test that we can really sure we get what we want from WSS4J
223             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
224             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
225 
226             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
227             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
228         }
229 
230         //done signature; now test sig-verification:
231         {
232             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
233             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
234             securityProperties.addIgnoreBSPRule(BSPRule.R5417);
235             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
236 
237             WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
238                     WSSecurityEventConstants.KeyValueToken,
239                     WSSecurityEventConstants.OPERATION,
240             };
241             final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
242             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
243 
244             StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
245 
246             // Check principal
247             KeyValueTokenSecurityEvent event =
248                     (KeyValueTokenSecurityEvent)securityEventListener.getSecurityEvent(WSSecurityEventConstants.KeyValueToken);
249             assertNotNull(event);
250             KeyValueSecurityToken token = event.getSecurityToken();
251 
252             Principal principal = token.getPrincipal();
253             assertTrue(principal instanceof PublicKeyPrincipal);
254         }
255     }
256 
257     @Test
258     public void testDSAKeyValue() throws Exception {
259 
260         ByteArrayOutputStream baos = new ByteArrayOutputStream();
261         {
262             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
263             String action = WSHandlerConstants.SIGNATURE;
264             Properties properties = new Properties();
265             properties.put(WSHandlerConstants.SIG_KEY_ID, "KeyValue");
266             properties.put(WSHandlerConstants.SIGNATURE_USER, "transmitter-dsa");
267             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
268 
269             //some test that we can really sure we get what we want from WSS4J
270             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
271             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
272 
273             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
274             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
275         }
276 
277         //done signature; now test sig-verification:
278         {
279             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
280             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
281             securityProperties.addIgnoreBSPRule(BSPRule.R5417);
282             securityProperties.addIgnoreBSPRule(BSPRule.R5421);
283             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
284 
285             WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
286                     WSSecurityEventConstants.KeyValueToken,
287                     WSSecurityEventConstants.OPERATION,
288             };
289             final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
290             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
291 
292             StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
293 
294             // Check principal
295             KeyValueTokenSecurityEvent event =
296                     (KeyValueTokenSecurityEvent)securityEventListener.getSecurityEvent(WSSecurityEventConstants.KeyValueToken);
297             assertNotNull(event);
298             KeyValueSecurityToken token = event.getSecurityToken();
299 
300             Principal principal = token.getPrincipal();
301             assertTrue(principal instanceof PublicKeyPrincipal);
302         }
303     }
304 
305     @Test
306     public void testECKeyValue() throws Exception {
307 
308         //
309         // This test fails with the IBM JDK and with JDK 1.8
310         // TODO - Re-enable with JDK 1.8 when we fix Santuario
311         //
312         if ("IBM Corporation".equals(System.getProperty("java.vendor"))
313             || System.getProperty("java.version") != null
314                 && System.getProperty("java.version").startsWith("1.8")) {
315             return;
316         }
317 
318         ByteArrayOutputStream baos = new ByteArrayOutputStream();
319         {
320             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
321             String action = WSHandlerConstants.SIGNATURE;
322             Properties properties = new Properties();
323             properties.put(WSHandlerConstants.SIG_KEY_ID, "KeyValue");
324             properties.put(WSHandlerConstants.SIGNATURE_USER, "transmitter-ecdsa");
325             properties.put(WSHandlerConstants.SIG_ALGO, "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512");
326             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
327 
328             //some test that we can really sure we get what we want from WSS4J
329             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
330             assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
331 
332             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
333             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
334         }
335 
336         //done signature; now test sig-verification:
337         {
338             WSSSecurityProperties securityProperties = new WSSSecurityProperties();
339             securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
340             securityProperties.addIgnoreBSPRule(BSPRule.R5417);
341             securityProperties.addIgnoreBSPRule(BSPRule.R5421);
342             InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
343 
344             WSSecurityEventConstants.Event[] expectedSecurityEvents = new WSSecurityEventConstants.Event[]{
345                     WSSecurityEventConstants.KeyValueToken,
346                     WSSecurityEventConstants.OPERATION,
347             };
348             final TestSecurityEventListener securityEventListener = new TestSecurityEventListener(expectedSecurityEvents);
349             XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())), null, securityEventListener);
350 
351             StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
352 
353             // Check principal
354             KeyValueTokenSecurityEvent event =
355                     (KeyValueTokenSecurityEvent)securityEventListener.getSecurityEvent(WSSecurityEventConstants.KeyValueToken);
356             assertNotNull(event);
357             KeyValueSecurityToken token = event.getSecurityToken();
358 
359             Principal principal = token.getPrincipal();
360             assertTrue(principal instanceof PublicKeyPrincipal);
361         }
362     }
363 }