View Javadoc

1   /*
2    * $Id: WsSecurityFilter.java 10165 2007-12-28 11:34:33Z marie.rizzo $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.extras.wssecurity.filters;
12  
13  import org.mule.MuleManager;
14  import org.mule.config.i18n.MessageFactory;
15  import org.mule.extras.wssecurity.handlers.MuleWSSInHandler;
16  import org.mule.impl.MuleMessage;
17  import org.mule.impl.security.AbstractEndpointSecurityFilter;
18  import org.mule.providers.soap.axis.AxisConnector;
19  import org.mule.providers.soap.axis.extensions.MuleConfigProvider;
20  import org.mule.providers.soap.xfire.XFireConnector;
21  import org.mule.umo.UMOEvent;
22  import org.mule.umo.lifecycle.InitialisationException;
23  import org.mule.umo.security.CryptoFailureException;
24  import org.mule.umo.security.EncryptionStrategyNotFoundException;
25  import org.mule.umo.security.SecurityException;
26  import org.mule.umo.security.SecurityProviderNotFoundException;
27  import org.mule.umo.security.UnknownAuthenticationTypeException;
28  import org.mule.umo.security.UnsupportedAuthenticationSchemeException;
29  
30  import java.util.ArrayList;
31  import java.util.Hashtable;
32  import java.util.List;
33  import java.util.Map;
34  import java.util.Properties;
35  
36  import javax.xml.namespace.QName;
37  
38  import org.apache.axis.ConfigurationException;
39  import org.apache.axis.Handler;
40  import org.apache.axis.handlers.soap.SOAPService;
41  import org.apache.axis.server.AxisServer;
42  import org.apache.ws.axis.security.WSDoAllReceiver;
43  import org.apache.ws.axis.security.WSDoAllSender;
44  import org.apache.ws.security.handler.WSHandlerConstants;
45  import org.codehaus.xfire.XFire;
46  import org.codehaus.xfire.security.wss4j.WSS4JOutHandler;
47  import org.codehaus.xfire.service.Service;
48  import org.codehaus.xfire.util.dom.DOMInHandler;
49  import org.codehaus.xfire.util.dom.DOMOutHandler;
50  
51  public class WsSecurityFilter extends AbstractEndpointSecurityFilter
52  {
53      private String wsDecryptionFile = null;
54      private String wsSignatureFile = null;
55      private Map addOutboundProperties = null;
56      private Map addInboundProperties = null;
57  
58      public String getWsDecryptionFile()
59      {
60          return wsDecryptionFile;
61      }
62  
63      public void setWsDecryptionFile(String wsDecryptionFile)
64      {
65          this.wsDecryptionFile = wsDecryptionFile;
66      }
67  
68      public String getWsSignatureFile()
69      {
70          return wsSignatureFile;
71      }
72  
73      public void setWsSignatureFile(String wsSignatureFile)
74      {
75          this.wsSignatureFile = wsSignatureFile;
76      }
77  
78      /**
79       * This method's use is two-fold. First it sets the required security handlers on
80       * the service. Secondly, it checks the properties in the message and if there
81       * are security properties among them, it sets them on the service.
82       */
83      protected void authenticateInbound(UMOEvent event)
84          throws SecurityException, CryptoFailureException, SecurityProviderNotFoundException,
85          EncryptionStrategyNotFoundException, UnknownAuthenticationTypeException
86      {
87          Map properties = event.getSession().getComponent().getDescriptor().getProperties();
88          if (properties.containsKey("xfire"))
89          {
90              XFire server = (XFire)properties.get("xfire");
91              String pathInfo = event.getEndpoint().getEndpointURI().getPath();
92  
93              String serviceName;
94              int i = pathInfo.lastIndexOf('/');
95  
96              if (i > -1)
97              {
98                  serviceName = pathInfo.substring(i + 1);
99              }
100             else
101             {
102                 serviceName = pathInfo;
103             }
104 
105             Service service = server.getServiceRegistry().getService(serviceName);
106              
107             // remove security in handlers if present
108                   
109             Object[] connectorArray = MuleManager.getInstance().getConnectors().values().toArray();
110             XFireConnector connector = null;
111             XFireConnector tempConnector = null;
112             
113             for (int iter = 0; iter < connectorArray.length; iter++)
114             {
115                 if (connectorArray[iter] instanceof XFireConnector)
116                 {
117                     tempConnector = (XFireConnector)connectorArray[iter];
118 
119                     if (tempConnector.getReceivers(event.getEndpoint().getEndpointURI().toString()).length == 0)
120                     {
121                         connector = null;
122                     }
123                     else
124                     {
125                         connector = tempConnector;
126                         iter = connectorArray.length;
127                     }
128                 }
129             }
130 
131             if (connector != null){
132                 Object[] outhandlers = service.getOutHandlers().toArray();
133                 for (i = 0; i < outhandlers.length; i++)
134                 {
135                     if (outhandlers[i] instanceof DOMOutHandler)
136                     {
137                         connector.getClientOutHandlers().remove(i);
138                     }
139                     if (outhandlers[i] instanceof WSS4JOutHandler)
140                     {
141                         connector.getClientOutHandlers().remove(i);
142                     }
143                 }
144     
145                 // add security out handlers if not present
146                 Object[] handlers = service.getInHandlers().toArray();
147                 boolean isDomInHandlerPresent = false;
148                 boolean isWss4jInHandlerPresent = false;
149                 for (i = 0; i < handlers.length; i++)
150                 {
151                     if (handlers[i] instanceof DOMInHandler)
152                     {
153                         isDomInHandlerPresent = true;
154                     }
155                     if (handlers[i] instanceof MuleWSSInHandler)
156                     {
157                         isWss4jInHandlerPresent = true;
158                     }
159                 }
160     
161                 if (!isDomInHandlerPresent)
162                 {
163                     service.addInHandler(new DOMInHandler());
164                 }
165     
166                 if (!isWss4jInHandlerPresent)
167                 {
168                     service.addInHandler(new MuleWSSInHandler());
169                 }
170                 
171                 // set properties on service
172                 if (service.getProperty("action") == null)
173                 {
174                     if (connector.getExtraProperties() != null)
175                     {
176                         Properties props = new Properties();
177                         props.putAll(connector.getExtraProperties());
178                         if (addInboundProperties != null)
179                         {
180                             props.putAll(addInboundProperties);
181                         }
182                         Object[] keys = props.keySet().toArray();
183                         for (i = 0; i < props.size(); i++)
184                         {
185                             service.setProperty(keys[i].toString(), props.getProperty((String)keys[i]));
186                         }
187                     }
188                     else
189                     {
190                         // use defaults
191                         service.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
192                         service.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, "org.mule.extras.wssecurity.callbackhandlers.MuleWsSecurityCallbackHandler");
193 
194                         if (addInboundProperties != null)
195                         {
196                             Properties props = new Properties();
197                             props.putAll(this.addInboundProperties);
198                             Object[] keys = props.keySet().toArray();
199                             for (i = 0; i < props.size(); i++)
200                             {
201                                 service.setProperty(keys[i].toString(), props.getProperty((String)keys[i]));
202                             }
203                         }
204                     }
205                     if (wsDecryptionFile != null)
206                     {
207                         service.setProperty(WSHandlerConstants.DEC_PROP_FILE, wsDecryptionFile);
208                     }
209                     if (wsSignatureFile != null)
210                     {
211                         service.setProperty(WSHandlerConstants.SIG_PROP_FILE, wsSignatureFile);
212                     }
213                 }
214             }
215         }
216         else if (properties.containsKey("axisServer"))
217         {
218             AxisServer server = (AxisServer)event.getSession().getComponent().getDescriptor()
219                 .getProperties().get("axisServer");
220             MuleConfigProvider provider = (MuleConfigProvider)server.getConfig();
221 
222             String prefix = event.getEndpoint().getProtocol() + ":";
223             String serviceName = event.getEndpoint().getName().substring(prefix.length());
224             SOAPService soapService;
225 
226             // set required security handlers
227             try
228             {
229                 soapService = provider.getService(new QName(serviceName));
230 
231                 Hashtable options = new Hashtable();
232                 if (event.getMessage().getProperty("action") != null)
233                 {
234                     options.putAll(getProperties(event));
235                     soapService.setPropertyParent(options);
236                     Handler inHandler = new WSDoAllReceiver();
237                     provider.setGlobalRequest(inHandler);
238                 }
239             }
240             catch (ConfigurationException e)
241             {
242                 throw new UnsupportedAuthenticationSchemeException(MessageFactory.createStaticMessage("A Configurtation Exception occured while configuring WS-Security on Axis "),new MuleMessage(e.getMessage()));
243             }
244         }
245     }
246 
247     /**
248      * This method secures the outgouing message by setting the required security
249      * handlers.
250      */
251     protected void authenticateOutbound(UMOEvent event)
252         throws SecurityException, SecurityProviderNotFoundException, CryptoFailureException
253     {
254         if (event.getEndpoint().getConnector() instanceof XFireConnector)
255         {
256             XFireConnector connector = (XFireConnector)event.getEndpoint().getConnector();
257             Map properties = event.getSession().getComponent().getDescriptor().getProperties();
258             XFire server = (XFire)properties.get("xfire");
259             
260             if (server == null)
261             {
262                 server = connector.getXfire();
263             }
264             
265             if (server != null)
266             {                      
267                 List clientHandlers = new ArrayList();
268                 List existingOutHandlers = connector.getClientOutHandlers();
269     
270                 clientHandlers.add("org.codehaus.xfire.util.dom.DOMOutHandler");
271                 clientHandlers.add("org.codehaus.xfire.security.wss4j.WSS4JOutHandler");
272     
273                 if (existingOutHandlers == null)
274                 {
275                     connector.setClientOutHandlers(clientHandlers);
276                 }
277                 else if (!existingOutHandlers
278                     .contains("org.codehaus.xfire.security.wss4j.WSS4JOutHandler"))
279                 {
280                     connector.setClientOutHandlers(clientHandlers);
281                 }
282                 
283                 if (addOutboundProperties != null)
284                 {
285                     connector.setExtraProperties(getAddOutboundProperties());
286                 }
287             }
288         }
289         else if (event.getEndpoint().getConnector() instanceof AxisConnector)
290         {
291             AxisConnector connector = (AxisConnector)event.getEndpoint().getConnector();
292             
293             if (connector.getClientProvider() != null)
294             {
295                 String[] processString = event.getEndpoint().getEndpointURI().toString().split("://");
296                     
297                 while (processString.length > 1){
298                     processString = processString[1].split("/");
299                 }
300     
301                 Handler outHandler = new WSDoAllSender();
302                 
303                 if (addOutboundProperties != null)
304                 {
305                     outHandler.setOptions(new Hashtable(getAddOutboundProperties()));
306                 }
307                 connector.getClientProvider().setGlobalRequest(outHandler);
308             }
309         }
310     }
311 
312     protected void doInitialise() throws InitialisationException
313     {
314         // Empty... Does not need to do anything for now
315     }
316 
317     /**
318      * This method gets the decryption and the signature property files and returns
319      * them as properties to the calling method.
320      * 
321      * @param event
322      * @return
323      */
324     protected Properties getProperties(UMOEvent event)
325     {
326         Properties props = new Properties();
327 
328         if (wsDecryptionFile != null)
329         {
330             props.put(WSHandlerConstants.DEC_PROP_FILE, wsDecryptionFile);
331         }
332         if (wsSignatureFile != null)
333         {
334             props.put(WSHandlerConstants.SIG_PROP_FILE, wsSignatureFile);
335         }
336         return props;
337     }
338 
339     public Map getAddOutboundProperties()
340     {
341         return addOutboundProperties;
342     }
343 
344     public void setAddOutboundProperties(Map addOutboundProperties)
345     {
346         this.addOutboundProperties = addOutboundProperties;
347     }
348 
349     public Map getAddInboundProperties() {
350         return addInboundProperties;
351     }
352 
353     public void setAddInboundProperties(Map addInboundProperties) {
354         this.addInboundProperties = addInboundProperties;
355     }
356 }