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