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  
20  package org.apache.wss4j.dom.saml;
21  
22  import java.util.ArrayList;
23  import java.util.Collections;
24  import java.util.List;
25  
26  import javax.security.auth.callback.CallbackHandler;
27  
28  import org.apache.wss4j.common.util.SOAPUtil;
29  import org.w3c.dom.Document;
30  import org.apache.wss4j.common.crypto.Crypto;
31  import org.apache.wss4j.common.crypto.CryptoFactory;
32  import org.apache.wss4j.common.ext.WSSecurityException;
33  import org.apache.wss4j.common.saml.SamlAssertionWrapper;
34  import org.apache.wss4j.common.util.XMLUtils;
35  import org.apache.wss4j.dom.WSConstants;
36  import org.apache.wss4j.dom.common.CustomHandler;
37  import org.apache.wss4j.dom.common.CustomSamlAssertionValidator;
38  import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
39  import org.apache.wss4j.dom.common.SAML1CallbackHandler;
40  import org.apache.wss4j.dom.common.SAML2CallbackHandler;
41  
42  import org.apache.wss4j.dom.engine.WSSConfig;
43  import org.apache.wss4j.dom.engine.WSSecurityEngine;
44  import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
45  import org.apache.wss4j.dom.handler.HandlerAction;
46  import org.apache.wss4j.dom.handler.RequestData;
47  import org.apache.wss4j.dom.handler.WSHandlerConstants;
48  import org.apache.wss4j.dom.handler.WSHandlerResult;
49  
50  import org.junit.jupiter.api.Test;
51  
52  import static org.junit.jupiter.api.Assertions.assertEquals;
53  import static org.junit.jupiter.api.Assertions.assertFalse;
54  import static org.junit.jupiter.api.Assertions.assertNotNull;
55  import static org.junit.jupiter.api.Assertions.assertTrue;
56  
57  /**
58   * Test-case for sending SAML Assertions using the "action" approach.
59   */
60  public class SamlTokenActionTest {
61      private static final org.slf4j.Logger LOG =
62          org.slf4j.LoggerFactory.getLogger(SamlTokenActionTest.class);
63      private WSSecurityEngine secEngine = new WSSecurityEngine();
64      private Crypto crypto;
65  
66      public SamlTokenActionTest() throws WSSecurityException {
67          WSSConfig config = WSSConfig.getNewInstance();
68          crypto = CryptoFactory.getInstance("wss40.properties");
69          config.setValidator(WSConstants.SAML_TOKEN, new CustomSamlAssertionValidator());
70          config.setValidator(WSConstants.SAML2_TOKEN, new CustomSamlAssertionValidator());
71          secEngine.setWssConfig(config);
72      }
73  
74      @Test
75      public void testAssertionAction() throws Exception {
76          final WSSConfig cfg = WSSConfig.getNewInstance();
77          final RequestData reqData = new RequestData();
78          reqData.setWssConfig(cfg);
79          reqData.setUsername("wss40");
80  
81          CallbackHandler callbackHandler = new KeystoreCallbackHandler();
82  
83          SAML1CallbackHandler samlCallbackHandler = new SAML1CallbackHandler();
84          samlCallbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
85          samlCallbackHandler.setIssuer("www.example.com");
86  
87          java.util.Map<String, Object> config = new java.util.TreeMap<>();
88          config.put(WSHandlerConstants.SIG_PROP_FILE, "wss40.properties");
89          config.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
90          config.put(WSHandlerConstants.SAML_CALLBACK_REF, samlCallbackHandler);
91          reqData.setMsgContext(config);
92  
93          final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
94          CustomHandler handler = new CustomHandler();
95          HandlerAction action = new HandlerAction(WSConstants.ST_UNSIGNED);
96          handler.send(
97              doc,
98              reqData,
99              Collections.singletonList(action),
100             true
101         );
102         if (LOG.isDebugEnabled()) {
103             String outputString = XMLUtils.prettyDocumentToString(doc);
104             LOG.debug(outputString);
105         }
106 
107         WSHandlerResult results = verify(doc, callbackHandler);
108         WSSecurityEngineResult actionResult =
109             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
110 
111         SamlAssertionWrapper receivedSamlAssertion =
112             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
113         assertNotNull(receivedSamlAssertion);
114         assertFalse(receivedSamlAssertion.isSigned());
115     }
116 
117     @Test
118     public void testAssertionActionWithSAAJ() throws Exception {
119         final WSSConfig cfg = WSSConfig.getNewInstance();
120         final RequestData reqData = new RequestData();
121         reqData.setWssConfig(cfg);
122         reqData.setUsername("wss40");
123 
124         CallbackHandler callbackHandler = new KeystoreCallbackHandler();
125 
126         SAML1CallbackHandler samlCallbackHandler = new SAML1CallbackHandler();
127         samlCallbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
128         samlCallbackHandler.setIssuer("www.example.com");
129 
130         java.util.Map<String, Object> config = new java.util.TreeMap<>();
131         config.put(WSHandlerConstants.SIG_PROP_FILE, "wss40.properties");
132         config.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
133         config.put(WSHandlerConstants.SAML_CALLBACK_REF, samlCallbackHandler);
134         reqData.setMsgContext(config);
135 
136         final Document doc = SOAPUtil.toSAAJSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
137         CustomHandler handler = new CustomHandler();
138         HandlerAction action = new HandlerAction(WSConstants.ST_UNSIGNED);
139         handler.send(
140             doc,
141             reqData,
142             Collections.singletonList(action),
143             true
144         );
145         if (LOG.isDebugEnabled()) {
146             String outputString = XMLUtils.prettyDocumentToString(doc);
147             LOG.debug(outputString);
148         }
149 
150         WSHandlerResult results = verify(doc, callbackHandler);
151         WSSecurityEngineResult actionResult =
152             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
153 
154         SamlAssertionWrapper receivedSamlAssertion =
155             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
156         assertNotNull(receivedSamlAssertion);
157         assertFalse(receivedSamlAssertion.isSigned());
158     }
159 
160 
161     @Test
162     public void testSignedAssertionAction() throws Exception {
163         final WSSConfig cfg = WSSConfig.getNewInstance();
164         final RequestData reqData = new RequestData();
165         reqData.setWssConfig(cfg);
166 
167         CallbackHandler callbackHandler = new KeystoreCallbackHandler();
168 
169         SAML1CallbackHandler samlCallbackHandler = new SAML1CallbackHandler();
170         samlCallbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
171         samlCallbackHandler.setIssuer("www.example.com");
172         samlCallbackHandler.setIssuerCrypto(crypto);
173         samlCallbackHandler.setIssuerName("wss40");
174         samlCallbackHandler.setIssuerPassword("security");
175         samlCallbackHandler.setSignAssertion(true);
176 
177         java.util.Map<String, Object> config = new java.util.TreeMap<>();
178         config.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
179         config.put(WSHandlerConstants.SAML_CALLBACK_REF, samlCallbackHandler);
180         reqData.setMsgContext(config);
181 
182         final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
183         CustomHandler handler = new CustomHandler();
184         HandlerAction action = new HandlerAction(WSConstants.ST_SIGNED);
185         handler.send(
186             doc,
187             reqData,
188             Collections.singletonList(action),
189             true
190         );
191         if (LOG.isDebugEnabled()) {
192             String outputString = XMLUtils.prettyDocumentToString(doc);
193             LOG.debug(outputString);
194         }
195 
196         WSHandlerResult results = verify(doc, callbackHandler);
197         assertEquals(2, results.getActionResults().keySet().size());
198         WSSecurityEngineResult actionResult =
199             results.getActionResults().get(WSConstants.ST_SIGNED).get(0);
200 
201         SamlAssertionWrapper receivedSamlAssertion =
202             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
203         assertNotNull(receivedSamlAssertion);
204         assertTrue(receivedSamlAssertion.isSigned());
205     }
206 
207     @Test
208     public void testAssertionWithSignatureAction() throws Exception {
209         final WSSConfig cfg = WSSConfig.getNewInstance();
210         final RequestData reqData = new RequestData();
211         reqData.setWssConfig(cfg);
212         reqData.setUsername("wss40");
213 
214         CallbackHandler callbackHandler = new KeystoreCallbackHandler();
215 
216         SAML1CallbackHandler samlCallbackHandler = new SAML1CallbackHandler();
217         samlCallbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
218         samlCallbackHandler.setIssuer("www.example.com");
219 
220         java.util.Map<String, Object> config = new java.util.TreeMap<>();
221         config.put(WSHandlerConstants.SIG_PROP_FILE, "wss40.properties");
222         config.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
223         config.put(WSHandlerConstants.SAML_CALLBACK_REF, samlCallbackHandler);
224         config.put(WSHandlerConstants.SIGNATURE_PARTS, "{}{" + WSConstants.SAML_NS + "}Assertion;");
225         reqData.setMsgContext(config);
226 
227         final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
228         CustomHandler handler = new CustomHandler();
229         List<HandlerAction> actions = new ArrayList<>();
230         actions.add(new HandlerAction(WSConstants.ST_UNSIGNED));
231         actions.add(new HandlerAction(WSConstants.SIGN));
232         handler.send(
233             doc,
234             reqData,
235             actions,
236             true
237         );
238         if (LOG.isDebugEnabled()) {
239             String outputString = XMLUtils.prettyDocumentToString(doc);
240             LOG.debug(outputString);
241         }
242 
243         WSHandlerResult results = verify(doc, callbackHandler);
244         WSSecurityEngineResult actionResult =
245             results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
246 
247         SamlAssertionWrapper receivedSamlAssertion =
248             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
249         assertNotNull(receivedSamlAssertion);
250         assertFalse(receivedSamlAssertion.isSigned());
251     }
252 
253     @Test
254     public void testSignedSAML2AssertionAction() throws Exception {
255         final WSSConfig cfg = WSSConfig.getNewInstance();
256         final RequestData reqData = new RequestData();
257         reqData.setWssConfig(cfg);
258         reqData.setUsername("wss40");
259 
260         CallbackHandler callbackHandler = new KeystoreCallbackHandler();
261 
262         SAML2CallbackHandler samlCallbackHandler = new SAML2CallbackHandler();
263         samlCallbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
264         samlCallbackHandler.setIssuer("www.example.com");
265         samlCallbackHandler.setSignAssertion(true);
266         samlCallbackHandler.setIssuerCrypto(crypto);
267         samlCallbackHandler.setIssuerName("wss40");
268         samlCallbackHandler.setIssuerPassword("security");
269 
270         java.util.Map<String, Object> config = new java.util.TreeMap<>();
271         config.put(WSHandlerConstants.SAML_CALLBACK_REF, samlCallbackHandler);
272         reqData.setMsgContext(config);
273 
274         final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
275         CustomHandler handler = new CustomHandler();
276         HandlerAction action = new HandlerAction(WSConstants.ST_UNSIGNED);
277         handler.send(
278             doc,
279             reqData,
280             Collections.singletonList(action),
281             true
282         );
283         if (LOG.isDebugEnabled()) {
284             String outputString = XMLUtils.prettyDocumentToString(doc);
285             LOG.debug(outputString);
286         }
287 
288         WSHandlerResult results = verify(doc, callbackHandler);
289         WSSecurityEngineResult actionResult =
290             results.getActionResults().get(WSConstants.ST_SIGNED).get(0);
291 
292         SamlAssertionWrapper receivedSamlAssertion =
293             (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
294         assertNotNull(receivedSamlAssertion);
295         assertTrue(receivedSamlAssertion.isSigned());
296     }
297 
298     private WSHandlerResult verify(
299         Document doc, CallbackHandler callbackHandler
300     ) throws Exception {
301         RequestData requestData = new RequestData();
302         requestData.setCallbackHandler(callbackHandler);
303         requestData.setDecCrypto(crypto);
304         requestData.setSigVerCrypto(crypto);
305         requestData.setValidateSamlSubjectConfirmation(false);
306 
307         WSHandlerResult results = secEngine.processSecurityHeader(doc, requestData);
308         String outputString =
309             XMLUtils.prettyDocumentToString(doc);
310         assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : false);
311         return results;
312     }
313 
314 }