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.handler;
21  
22  import org.apache.wss4j.common.util.SOAPUtil;
23  import org.apache.wss4j.dom.WSConstants;
24  import org.apache.wss4j.dom.common.CustomAction;
25  import org.apache.wss4j.dom.common.CustomHandler;
26  import org.apache.wss4j.dom.common.CustomProcessor;
27  
28  import org.apache.wss4j.dom.engine.WSSConfig;
29  import org.apache.wss4j.dom.engine.WSSecurityEngine;
30  import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
31  import org.apache.wss4j.common.crypto.Crypto;
32  import org.apache.wss4j.common.crypto.CryptoFactory;
33  import org.apache.wss4j.common.ext.WSSecurityException;
34  import org.apache.wss4j.common.util.XMLUtils;
35  import org.apache.wss4j.dom.message.WSSecSignature;
36  import org.apache.wss4j.dom.message.WSSecHeader;
37  import org.apache.wss4j.dom.util.WSSecurityUtil;
38  
39  import org.junit.jupiter.api.Test;
40  import org.w3c.dom.Document;
41  
42  import java.util.Collections;
43  import java.util.List;
44  
45  import static org.junit.jupiter.api.Assertions.assertEquals;
46  import static org.junit.jupiter.api.Assertions.assertTrue;
47  import static org.junit.jupiter.api.Assertions.fail;
48  
49  
50  /**
51   * A test for adding custom actions/processors etc.
52   */
53  public class CustomActionProcessorTest {
54      private static final org.slf4j.Logger LOG =
55          org.slf4j.LoggerFactory.getLogger(CustomActionProcessorTest.class);
56      private Crypto crypto;
57  
58      public CustomActionProcessorTest() throws Exception {
59          WSSConfig.init();
60          crypto = CryptoFactory.getInstance();
61      }
62  
63      /**
64       * Test to see that a custom processor configured through a
65       * WSSConfig instance is called
66       */
67      @Test
68      public void
69      testCustomUserProcessor() throws Exception {
70          Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
71          WSSecHeader secHeader = new WSSecHeader(doc);
72          secHeader.insertSecurityHeader();
73  
74          WSSecSignature builder = new WSSecSignature(secHeader);
75          builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
76          builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
77          LOG.info("Before Signing IS....");
78          Document signedDoc = builder.build(crypto);
79  
80          if (LOG.isDebugEnabled()) {
81              LOG.debug("Signed message with IssuerSerial key identifier:");
82              String outputString =
83                  XMLUtils.prettyDocumentToString(signedDoc);
84              LOG.debug(outputString);
85          }
86          LOG.info("After Signing IS....");
87          //
88          // Check to make sure we can install/replace and use our own processor
89          //
90          WSSConfig cfg = WSSConfig.getNewInstance();
91          String p = "org.apache.wss4j.dom.common.CustomProcessor";
92          cfg.setProcessor(
93              WSConstants.SIGNATURE, CustomProcessor.class
94          );
95          final WSSecurityEngine engine = new WSSecurityEngine();
96          engine.setWssConfig(cfg);
97          final WSHandlerResult results =
98              engine.processSecurityHeader(doc, null, null, crypto);
99          boolean found = false;
100         for (WSSecurityEngineResult result : results.getResults()) {
101             Object obj = result.get("foo");
102             if (obj != null && obj.getClass().getName().equals(p)) {
103                 found = true;
104             }
105         }
106         assertTrue(found, "Unable to find result from CustomProcessor");
107     }
108 
109     /**
110      * Test to see that a custom processor (object) configured through a
111      * WSSConfig instance is called
112      */
113     @Test
114     public void
115     testCustomUserProcessorObject() throws Exception {
116         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
117         WSSecHeader secHeader = new WSSecHeader(doc);
118         secHeader.insertSecurityHeader();
119 
120         WSSecSignature builder = new WSSecSignature(secHeader);
121         builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
122         builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
123         LOG.info("Before Signing IS....");
124         Document signedDoc = builder.build(crypto);
125 
126         if (LOG.isDebugEnabled()) {
127             LOG.debug("Signed message with IssuerSerial key identifier:");
128             String outputString =
129                 XMLUtils.prettyDocumentToString(signedDoc);
130             LOG.debug(outputString);
131         }
132         LOG.info("After Signing IS....");
133         //
134         // Check to make sure we can install/replace and use our own processor
135         //
136         WSSConfig cfg = WSSConfig.getNewInstance();
137         cfg.setProcessor(WSConstants.SIGNATURE, CustomProcessor.class);
138 
139         final WSSecurityEngine engine = new WSSecurityEngine();
140         engine.setWssConfig(cfg);
141         final WSHandlerResult results =
142             engine.processSecurityHeader(doc, null, null, crypto);
143         boolean found = false;
144         for (WSSecurityEngineResult result : results.getResults()) {
145             Object obj = result.get("foo");
146             if (obj != null && obj.getClass().getName().equals(CustomProcessor.class.getName())) {
147                 found = true;
148             }
149         }
150         assertTrue(found, "Unable to find result from CustomProcessor");
151     }
152 
153     /**
154      * Test to see that a custom action configured through a
155      * WSSConfig instance is called
156      */
157     @Test
158     public void
159     testCustomAction() throws Exception {
160 
161         final WSSConfig cfg = WSSConfig.getNewInstance();
162         final int action = 0xDEADF000;
163         cfg.setAction(action, CustomAction.class);
164         final RequestData reqData = new RequestData();
165         reqData.setWssConfig(cfg);
166 
167         final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
168         CustomHandler handler = new CustomHandler();
169         reqData.setMsgContext("bread");
170         assertEquals(reqData.getMsgContext(), "bread");
171         handler.send(
172             doc,
173             reqData,
174             Collections.singletonList(new HandlerAction(action)),
175             true
176         );
177         assertEquals(reqData.getMsgContext(), "crumb");
178     }
179 
180     /**
181      * Test to see that a custom action object configured through a
182      * WSSConfig instance is called
183      */
184     @Test
185     public void
186     testCustomActionObject() throws Exception {
187 
188         final WSSConfig cfg = WSSConfig.getNewInstance();
189         final int action = 0xDEADF000;
190         cfg.setAction(action, CustomAction.class);
191         final RequestData reqData = new RequestData();
192         reqData.setWssConfig(cfg);
193 
194         final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
195         CustomHandler handler = new CustomHandler();
196         reqData.setMsgContext("bread");
197         assertEquals(reqData.getMsgContext(), "bread");
198         handler.send(
199             doc,
200             reqData,
201             Collections.singletonList(new HandlerAction(action)),
202             true
203         );
204         assertEquals(reqData.getMsgContext(), "crumb");
205     }
206 
207     /**
208      * Test to see that a custom action can be configured via WSSecurityUtil.decodeAction.
209      * A standard Timestamp action is also configured.
210      */
211     @Test
212     public void
213     testDecodeCustomAction() throws Exception {
214 
215         final WSSConfig cfg = WSSConfig.getNewInstance();
216         final int customAction = 0xDEADF000;
217 
218         String actionString =
219             WSHandlerConstants.TIMESTAMP + " " + Integer.valueOf(customAction).toString();
220         //
221         // This parsing will fail as WSSConfig doesn't know what the custom action is
222         //
223         try {
224             WSSecurityUtil.decodeHandlerAction(actionString, cfg);
225             fail("Failure expected on unknown action");
226         } catch (WSSecurityException ex) {
227             assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
228         }
229 
230         //
231         // This parsing will fail as the action String is badly formed
232         //
233         try {
234             String badActionString =
235                 WSHandlerConstants.TIMESTAMP + " " + "NewCustomAction";
236             WSSecurityUtil.decodeHandlerAction(badActionString, cfg);
237             fail("Failure expected on unknown action");
238         } catch (WSSecurityException ex) {
239             assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
240         }
241 
242         //
243         // This parsing should pass as WSSConfig has been configured with the custom action
244         //
245         cfg.setAction(customAction, CustomAction.class);
246         List<HandlerAction> actionList = WSSecurityUtil.decodeHandlerAction(actionString, cfg);
247 
248         final RequestData reqData = new RequestData();
249         reqData.setWssConfig(cfg);
250 
251         final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
252         CustomHandler handler = new CustomHandler();
253         reqData.setMsgContext("bread");
254         assertEquals(reqData.getMsgContext(), "bread");
255         handler.send(
256             doc,
257             reqData,
258             actionList,
259             true
260         );
261         assertEquals(reqData.getMsgContext(), "crumb");
262 
263         if (LOG.isDebugEnabled()) {
264             LOG.debug("Message:");
265             String outputString =
266                 XMLUtils.prettyDocumentToString(doc);
267             LOG.debug(outputString);
268         }
269     }
270 
271 }