View Javadoc

1   /*
2    * $Id: WsSecurityFilter.java 7976 2007-08-21 14:26:13Z dirk.olmes $
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.extras.wssecurity.headers.WsSecurityHeadersSetter;
17  import org.mule.impl.MuleMessage;
18  import org.mule.impl.security.AbstractEndpointSecurityFilter;
19  import org.mule.providers.soap.axis.AxisConnector;
20  import org.mule.providers.soap.axis.extensions.MuleConfigProvider;
21  import org.mule.providers.soap.xfire.XFireConnector;
22  import org.mule.umo.UMOEvent;
23  import org.mule.umo.lifecycle.InitialisationException;
24  import org.mule.umo.security.CryptoFailureException;
25  import org.mule.umo.security.EncryptionStrategyNotFoundException;
26  import org.mule.umo.security.SecurityException;
27  import org.mule.umo.security.SecurityProviderNotFoundException;
28  import org.mule.umo.security.UnknownAuthenticationTypeException;
29  import org.mule.umo.security.UnsupportedAuthenticationSchemeException;
30  
31  import java.util.ArrayList;
32  import java.util.Hashtable;
33  import java.util.List;
34  import java.util.Map;
35  import java.util.Properties;
36  
37  import javax.xml.namespace.QName;
38  
39  import org.apache.axis.ConfigurationException;
40  import org.apache.axis.Handler;
41  import org.apache.axis.handlers.soap.SOAPService;
42  import org.apache.axis.server.AxisServer;
43  import org.apache.ws.axis.security.WSDoAllReceiver;
44  import org.apache.ws.axis.security.WSDoAllSender;
45  import org.apache.ws.security.handler.WSHandlerConstants;
46  import org.codehaus.xfire.XFire;
47  import org.codehaus.xfire.security.wss4j.WSS4JOutHandler;
48  import org.codehaus.xfire.service.Service;
49  import org.codehaus.xfire.util.dom.DOMInHandler;
50  import org.codehaus.xfire.util.dom.DOMOutHandler;
51  
52  public class WsSecurityFilter extends AbstractEndpointSecurityFilter
53  {
54      private String wsDecryptionFile = null;
55      private String wsSignatureFile = null;
56      private Map addOutboundProperties = 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             Object[] connectorArray = MuleManager.getInstance().getConnectors().values().toArray();
109             XFireConnector connector = null;
110             for (i = 0; i < connectorArray.length; i++)
111             {
112                 if (connectorArray[i] instanceof XFireConnector)
113                 {
114                     connector = (XFireConnector)connectorArray[i];
115                 }
116             }
117 
118             if (connector != null){
119                 Object[] outhandlers = service.getOutHandlers().toArray();
120                 for (i = 0; i < outhandlers.length; i++)
121                 {
122                     if (outhandlers[i] instanceof DOMOutHandler)
123                     {
124                         connector.getClientOutHandlers().remove(i);
125                     }
126                     if (outhandlers[i] instanceof WSS4JOutHandler)
127                     {
128                         connector.getClientOutHandlers().remove(i);
129                     }
130                 }
131     
132                 // add security out handlers if not present
133                 Object[] handlers = service.getInHandlers().toArray();
134                 boolean isDomInHandlerPresent = false;
135                 boolean isWss4jInHandlerPresent = false;
136                 for (i = 0; i < handlers.length; i++)
137                 {
138                     if (handlers[i] instanceof DOMInHandler)
139                     {
140                         isDomInHandlerPresent = true;
141                     }
142                     if (handlers[i] instanceof MuleWSSInHandler)
143                     {
144                         isWss4jInHandlerPresent = true;
145                     }
146                 }
147     
148                 if (!isDomInHandlerPresent)
149                 {
150                     service.addInHandler(new DOMInHandler());
151                 }
152     
153                 if (!isWss4jInHandlerPresent)
154                 {
155                     service.addInHandler(new MuleWSSInHandler());
156                 }
157     
158                 // look for security properties in the message
159                 Properties props = new Properties();
160                 if (event.getMessage().getProperty("action") != null)
161                 {
162                     props.putAll(getProperties(event));
163                 }
164     
165                 // put the security properties found in the message, if any, in the
166                 // service
167                 if (!props.isEmpty())
168                 {
169                     Object[] keys = props.keySet().toArray();
170                     for (i = 0; i < keys.length; i++)
171                     {
172                         service.setProperty((String)keys[i], props.getProperty((String)keys[i]));
173                     }
174                 }
175             }
176         }
177         else if (properties.containsKey("axisServer"))
178         {
179             AxisServer server = (AxisServer)event.getSession().getComponent().getDescriptor()
180                 .getProperties().get("axisServer");
181             MuleConfigProvider provider = (MuleConfigProvider)server.getConfig();
182 
183             String prefix = event.getEndpoint().getProtocol() + ":";
184             String serviceName = event.getEndpoint().getName().substring(prefix.length());
185             SOAPService soapService;
186 
187             // set required security handlers
188             try
189             {
190                 soapService = provider.getService(new QName(serviceName));
191 
192                 Hashtable options = new Hashtable();
193                 if (event.getMessage().getProperty("action") != null)
194                 {
195                     options.putAll(getProperties(event));
196                     soapService.setPropertyParent(options);
197                     Handler inHandler = new WSDoAllReceiver();
198                     provider.setGlobalRequest(inHandler);
199                 }
200             }
201             catch (ConfigurationException e)
202             {
203                 throw new UnsupportedAuthenticationSchemeException(MessageFactory.createStaticMessage("A Configurtation Exception occured while configuring WS-Security on Axis "),new MuleMessage(e.getMessage()));
204             }
205         }
206     }
207 
208     /**
209      * This method secures the outgouing message by setting the required security
210      * handlers.
211      */
212     protected void authenticateOutbound(UMOEvent event)
213         throws SecurityException, SecurityProviderNotFoundException, CryptoFailureException
214     {
215         if (event.getEndpoint().getConnector() instanceof XFireConnector)
216         {
217             XFireConnector connector = (XFireConnector)event.getEndpoint().getConnector();
218             Map properties = event.getSession().getComponent().getDescriptor().getProperties();
219             XFire server = (XFire)properties.get("xfire");
220             
221             if (server == null)
222             {
223                 server = connector.getXfire();
224             }
225             
226             if (server != null)
227             {                      
228                 List clientHandlers = new ArrayList();
229                 List existingOutHandlers = connector.getClientOutHandlers();
230     
231                 clientHandlers.add("org.codehaus.xfire.util.dom.DOMOutHandler");
232                 clientHandlers.add("org.codehaus.xfire.security.wss4j.WSS4JOutHandler");
233     
234                 if (existingOutHandlers == null)
235                 {
236                     connector.setClientOutHandlers(clientHandlers);
237                 }
238                 else if (!existingOutHandlers
239                     .contains("org.codehaus.xfire.security.wss4j.WSS4JOutHandler"))
240                 {
241                     connector.setClientOutHandlers(clientHandlers);
242                 }
243                 
244                 // look for security properties in the message
245                 Properties props = new Properties();  
246                 if (addOutboundProperties != null)
247                 {
248                     logger.warn("Properties set on the Security Filter will override those set on the message");
249                     props.putAll(getAddOutboundProperties());
250                     event.getMessage().addProperties(props);
251                 }
252             }
253         }
254         else if (event.getEndpoint().getConnector() instanceof AxisConnector)
255         {
256             AxisConnector connector = (AxisConnector)event.getEndpoint().getConnector();
257             
258             if (connector.getClientProvider() != null)
259             {
260                 String[] processString = event.getEndpoint().getEndpointURI().toString().split("://");
261                     
262                 while (processString.length > 1){
263                     processString = processString[1].split("/");
264                 }
265     
266                 Hashtable options = new Hashtable();
267                         
268                 if (addOutboundProperties != null)
269                 {
270                     logger.warn("Properties set on the Security Filter will override those set on the message");
271                     options.putAll(getAddOutboundProperties());
272                     event.getMessage().addProperties(options);
273                 }
274         
275                 Handler outHandler = new WSDoAllSender();
276                 connector.getClientProvider().setGlobalRequest(outHandler);
277             }
278         }
279     }
280 
281     protected void doInitialise() throws InitialisationException
282     {
283         // Empty... Does not need to do anything for now
284     }
285 
286     /**
287      * This method gets the decryption and the signature property files and returns
288      * them as properties to the calling method.
289      * 
290      * @param event
291      * @return
292      */
293     protected Properties getProperties(UMOEvent event)
294     {
295         WsSecurityHeadersSetter secHeaders = new WsSecurityHeadersSetter();
296 
297         Properties props2 = secHeaders.addSecurityHeaders(event.getMessage());
298 
299         Properties props = new Properties();
300 
301         if (wsDecryptionFile != null)
302         {
303             props.put(WSHandlerConstants.DEC_PROP_FILE, wsDecryptionFile);
304         }
305         if (wsSignatureFile != null)
306         {
307             props.put(WSHandlerConstants.SIG_PROP_FILE, wsSignatureFile);
308         }
309         props.putAll(props2);
310         return props;
311     }
312 
313     public Map getAddOutboundProperties()
314     {
315         return addOutboundProperties;
316     }
317 
318     public void setAddOutboundProperties(Map addOutboundProperties)
319     {
320         this.addOutboundProperties = addOutboundProperties;
321     }
322 }