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.StringWriter;
17  
18  import org.apache.ws.security.WSConstants;
19  import org.apache.ws.security.message.WSSecHeader;
20  import org.apache.ws.security.message.WSSecTimestamp;
21  import org.apache.ws.security.message.WSSecUsernameToken;
22  import org.w3c.dom.Document;
23  import org.w3c.dom.Element;
24  import org.xml.sax.SAXException;
25  
26  import com.eviware.soapui.SoapUI;
27  import com.eviware.soapui.impl.wsdl.WsdlRequest;
28  import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
29  import com.eviware.soapui.model.iface.SubmitContext;
30  import com.eviware.soapui.support.StringUtils;
31  import com.eviware.soapui.support.xml.XmlUtils;
32  
33  /***
34   * Modifies the request message to include WS-Securty Username and Timestamp tokens
35   * 
36   * @author Ole.Matzura
37   */
38  
39  public class WssAuthenticationRequestFilter extends AbstractWssRequestFilter
40  {
41  	private static final String WSS_USERNAME_TOKEN = "WsSecurityAuthenticationRequestFilter@UsernameToken";
42  	private static final String WSS_TIMESTAMP_TOKEN = "WsSecurityAuthenticationRequestFilter@TimestampToken";
43  
44  	public void filterRequest(SubmitContext context, WsdlRequest wsdlRequest)
45  	{
46  		String pwType = wsdlRequest.getWssPasswordType();
47        String wsTimestamp = wsdlRequest.getWssTimeToLive();
48        
49  		if (  (StringUtils.isNullOrEmpty( pwType ) || WsdlRequest.PW_TYPE_NONE.equals(pwType)) &&
50        		(StringUtils.isNullOrEmpty( wsTimestamp )))
51        		return;
52        try 
53        {
54          	setWssHeaders( context, wsdlRequest.getUsername(), wsdlRequest.getPassword(), pwType, wsTimestamp );
55        } 
56  		catch (Throwable e) 
57  		{
58            SoapUI.logError( e );
59        }
60  	}
61  
62  	public static void setWssHeaders( SubmitContext context, String username, String password, String pwType, String wsTimestamp ) throws SAXException, IOException
63  	{
64  		Document doc = getWssDocument( context );
65  		
66  		// create username token?
67  		if( StringUtils.hasContent( pwType ) && !pwType.equals( WsdlRequest.PW_TYPE_NONE ) && 
68  			 StringUtils.hasContent( username ) && StringUtils.hasContent( password ))
69  		{
70  			// remove if already set
71  			Element elm = ( Element ) context.getProperty( WSS_USERNAME_TOKEN );
72  			if( elm != null )
73  			{
74  				Element parentNode = ( Element ) elm.getParentNode();
75  				parentNode.removeChild( elm );
76  			}
77  			
78  			// save it so it can be removed.. 
79  			context.setProperty( WSS_USERNAME_TOKEN, setWssUsernameToken( username, password, pwType, doc ));
80  		}
81  		// remove if pwType is not null
82  		else if( pwType != null && context.getProperty( WSS_USERNAME_TOKEN ) != null )
83  		{
84  			Element elm = ( Element ) context.getProperty( WSS_USERNAME_TOKEN );
85  			context.removeProperty( WSS_USERNAME_TOKEN );
86  			Element parentNode = ( Element ) elm.getParentNode();
87  			parentNode.removeChild( elm );
88  			if( XmlUtils.getChildElements( parentNode ).getLength() == 0 )
89  				parentNode.getParentNode().removeChild( parentNode );
90  		}
91  
92  		// add timestamp?
93  		if( StringUtils.hasContent( wsTimestamp ) )
94  		{
95  			//	 remove if already set
96  			Element elm = ( Element ) context.getProperty( WSS_TIMESTAMP_TOKEN );
97  			if( elm != null )
98  			{
99  				Element parentNode = ( Element ) elm.getParentNode();
100 				parentNode.removeChild( elm );
101 			}
102 			
103 			//	save it so it can be removed.. 
104 			context.setProperty( WSS_TIMESTAMP_TOKEN, setWsTimestampToken( wsTimestamp, doc ));
105 		}
106 		// remove
107 		else if( wsTimestamp != null && context.getProperty( WSS_TIMESTAMP_TOKEN ) != null )
108 		{
109 			Element elm = ( Element ) context.getProperty( WSS_TIMESTAMP_TOKEN );
110 			context.removeProperty( WSS_TIMESTAMP_TOKEN );
111 			Element parentNode = ( Element ) elm.getParentNode();
112 			parentNode.removeChild( elm );
113 			if( XmlUtils.getChildElements( parentNode ).getLength() == 0 )
114 				parentNode.getParentNode().removeChild( parentNode );
115 		}
116 
117 		StringWriter writer = new StringWriter();
118 		XmlUtils.serializePretty( doc, writer );
119 		context.setProperty( BaseHttpRequestTransport.REQUEST_CONTENT, writer.toString() );
120 	}
121 
122 	private static Element setWsTimestampToken( String ttl, Document doc )
123 	{
124 		WSSecTimestamp addTimestamp = new WSSecTimestamp();
125 		addTimestamp.setTimeToLive( Integer.parseInt( ttl ));
126 		WSSecHeader secHeader = new WSSecHeader();
127 		secHeader.insertSecurityHeader( doc );
128 		addTimestamp.build( doc, secHeader );
129 		return addTimestamp.getElement();
130 	}
131 
132 	private static Element setWssUsernameToken( String username, String password, String pwType, Document doc )
133 	{
134 		WSSecUsernameToken wsa = new WSSecUsernameToken();
135 		if (WsdlRequest.PW_TYPE_DIGEST.equals(pwType)) 
136 		{
137 		   wsa.setPasswordType(WSConstants.PASSWORD_DIGEST);
138 		} 
139 		else 
140 		{
141 		   wsa.setPasswordType(WSConstants.PASSWORD_TEXT);
142 		}
143 		
144 		wsa.setUserInfo(username, password ); 
145 		wsa.addNonce();
146 		wsa.addCreated();
147 		
148 		WSSecHeader secHeader = new WSSecHeader();
149 		secHeader.insertSecurityHeader( doc );
150 		wsa.build(doc, secHeader );
151 		return wsa.getUsernameTokenElement();
152 	}
153 }