View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.wsdl.submit.filters;
14  
15  import java.io.IOException;
16  import java.io.StringReader;
17  import java.io.StringWriter;
18  
19  import javax.xml.parsers.DocumentBuilder;
20  import javax.xml.parsers.DocumentBuilderFactory;
21  import javax.xml.parsers.ParserConfigurationException;
22  
23  import org.apache.ws.security.WSConstants;
24  import org.apache.ws.security.message.WSSecHeader;
25  import org.apache.ws.security.message.WSSecTimestamp;
26  import org.apache.ws.security.message.WSSecUsernameToken;
27  import org.w3c.dom.Document;
28  import org.xml.sax.InputSource;
29  import org.xml.sax.SAXException;
30  
31  import com.eviware.soapui.SoapUI;
32  import com.eviware.soapui.impl.wsdl.WsdlRequest;
33  import com.eviware.soapui.impl.wsdl.submit.RequestFilter;
34  import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
35  import com.eviware.soapui.model.iface.SubmitContext;
36  import com.eviware.soapui.support.StringUtils;
37  import com.eviware.soapui.support.xml.XmlUtils;
38  
39  /***
40   * Modifies the request message to include WS-Securty Username and Timestamp tokens
41   * 
42   * @author Ole.Matzura
43   */
44  
45  public class WsSecurityAuthenticationRequestFilter implements RequestFilter
46  {
47  	private static DocumentBuilderFactory dbf;
48  	private static DocumentBuilder db;
49  
50  	static
51  	{
52  		dbf = DocumentBuilderFactory.newInstance();
53  		dbf.setValidating(false);
54  	   dbf.setNamespaceAware(true);
55  	   
56  	   try
57  		{
58  			db = dbf.newDocumentBuilder();
59  		}
60  		catch (ParserConfigurationException e)
61  		{
62  			SoapUI.logError( e );
63  		}
64  	}
65  
66  	public void filterRequest(SubmitContext context, WsdlRequest wsdlRequest)
67  	{
68  		String pwType = wsdlRequest.getWssPasswordType();
69        String wsTimestamp = wsdlRequest.getWssTimeToLive();
70        
71  		if (  (StringUtils.isNullOrEmpty( pwType ) || WsdlRequest.PW_TYPE_NONE.equals(pwType)) &&
72        		(StringUtils.isNullOrEmpty( wsTimestamp )))
73        		return;
74        try 
75        {
76          	addWssHeaders( context, wsdlRequest.getUsername(), wsdlRequest.getPassword(), pwType, wsTimestamp );
77        } 
78  		catch (Throwable e) 
79  		{
80            SoapUI.logError( e );
81        }
82  	}
83  
84  	public static void addWssHeaders( SubmitContext context, String username, String password, String pwType, String wsTimestamp ) throws SAXException, IOException
85  	{
86  		String request = (String) context.getProperty( BaseHttpRequestTransport.REQUEST_CONTENT );
87  		Document doc = null;
88  		
89  		// this should be solved with pooling for performance-reasons..
90  		synchronized( db )
91  		{
92  			doc = db.parse(new InputSource( new StringReader( request )));	
93  		}
94  		
95  		if( StringUtils.hasContent( pwType ) && !pwType.equals(  WsdlRequest.PW_TYPE_NONE ) && 
96  			 StringUtils.hasContent( username ) && StringUtils.hasContent( password ))
97  			addWssUsernameToken( username, password, pwType, doc );
98  
99  		if( StringUtils.hasContent( wsTimestamp ) )
100 			addWsTimestampToken( wsTimestamp, doc );
101 
102 		StringWriter writer = new StringWriter();
103 		XmlUtils.serializePretty( doc, writer );
104 		context.setProperty( BaseHttpRequestTransport.REQUEST_CONTENT, writer.toString() );
105 	}
106 
107 	private static void addWsTimestampToken( String ttl, Document doc )
108 	{
109 		WSSecTimestamp addTimestamp = new WSSecTimestamp();
110 		addTimestamp.setTimeToLive( Integer.parseInt( ttl ));
111 		WSSecHeader secHeader = new WSSecHeader();
112 		secHeader.insertSecurityHeader( doc );
113 		addTimestamp.build( doc, secHeader );
114 	}
115 
116 	private static void addWssUsernameToken( String username, String password, String pwType, Document doc )
117 	{
118 		WSSecUsernameToken wsa = new WSSecUsernameToken();
119 		if (WsdlRequest.PW_TYPE_DIGEST.equals(pwType)) 
120 		{
121 		   wsa.setPasswordType(WSConstants.PASSWORD_DIGEST);
122 		} 
123 		else 
124 		{
125 		   wsa.setPasswordType(WSConstants.PASSWORD_TEXT);
126 		}
127 		
128 		wsa.setUserInfo(username, password ); 
129 		
130 		WSSecHeader secHeader = new WSSecHeader();
131 		secHeader.insertSecurityHeader( doc );
132 		wsa.build(doc, secHeader );
133 	}
134 }