Home » Enterprise Java » Web Services » JAX-WS » Secure Metro JAX-WS UsernameToken Web Service with Signature, Encryption and TLS (SSL)

8 Flares Twitter 0 Facebook 0 Google+ 7 LinkedIn 1 Email -- Filament.io 8 Flares ×

Java Web Services Security: How to Secure JAX-WS UsernameToken Web Service with Signature, Encryption and TLS (SSL)

Securing the data exchanged between web service producers and consumers is essential to ensure confidentiality, authenticity and integrity of critical business data. There are many approaches to implement Web Service Security (WSS) popularly called as WS-Security. WS-Security is an extension to SOAP to apply security to web services.

Web Service Security

In a point-to-point situation, web service security aspects such as confidentiality and data integrity can be enforced on Web services, through the use of Transport Layer Security (TLS). Here the messages are sent over HTTPS.
In our previous example, we discussed message authentication using UsernameToken as a WS-Security mechanism. There neither we configured SSL to use transport level Security nor we encrypted or signed the authentication tokens. Sending cleartext username and password is not advisable on production environment.
The Message Authentication over SSL mechanism attaches a cryptographically secured identity or authentication token with the message and use SSL for confidentiality protection.

Symmetric Binding Security Assertion

In this article, we will see how we implement UsernameToken message authentication over SSL. We use the Symmetric binding security assertion to secure message exchanges. We also use transport binding assertion, since we use HTTPS as the message exchange transport medium.
When a symmetric binding is used, only one party needs to generate the security tokens. A symmetric key is established and using that security token further signing and encrypting is done. The symmetric binding can be used when only the server possesses a X509Token. Here, the client or consumer or initiator first creates an ephemeral key and then creates an encrypted key encrypting that ephemeral key using the recipient’s public key. In Other words the symmetric key is generated by initiator and is encrypted for recipient using recipient’s public key. Then this symmetric key is used by both initiator and recipient to sign and encrypt the messages back and forth. See the reference section to read more about WS Security Policy Language and Security Policy Assertions.

The UsernameToken Profile and Web Service Security

It is a good idea to understand the basics of UsernameToken and how it is used as a method to achieve Web service Security. I strongly recommend reading the following article before starting this excercise.

  • JAX-WS and Secure Java Web Services using UsernameToken : WS-Security with Metro and WSIT
  • Remember, unless password text or digested password is sent on a secured channel or the token is encrypted, neither password digest nor cleartext password offers no real additional security. The Web Services Security UsernameToken Profile 1.1 recommends that web service producers reject any UsernameToken not using both nonce and creation timestamps or with stale timestamps(to secure from replays) or with invalid tokens.
    In our example we will sign and encrypt the tokens and will send the message over secure HTTPS connection. We use Tomcat web container to deploy and test the application.

    Development tools required:

    • Eclipse IDE
    • Metro distribution
    • JDK7
    • Tomcat 6 or above

    If you have Netbeans IDE, generation of WSIT policy files are pretty easy. The IDE will generate them for you. I have chosen Eclipse IDE because manual creation of WSIT configuration files will help you to understand and apply the web security policies better.

    Setup the TLS (SSL) configurations on Web Server.

    Since we are using Tomcat web server as our jee container, we need to setup the SSL configurations in Tomcat server.xml file. A sample configuration is given below. To know more about how to configure SSL on Tomcat please read the below articles.

    Sample Tomcat server.xml TLS/SSL configuration.

    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
                   maxThreads="150" scheme="https" secure="true"
                   clientAuth="false" sslProtocol="TLS" 
    			   keystoreFile= "PATH_TO_YOUR_KEYSTORE_FILE”
    			   keystorePass="YOUR_KEYSTORE_PASSWORD"/>
    

    You need to configure your web.xml file to make sure that the traffic redirected to HTTPS port.

    Securing web applications in Web.xml

    The web.xml used in our sample application is below. Have a look at <security-constraint> configuration.

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    	id="WebApp_ID" version="2.5">
    
    	<display-name>MyWebService</display-name>
    	<description>my Web Service</description>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>MyService</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
    	<listener>
    		<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    	</listener>
    	<servlet>
    		<servlet-name>MyWebServicePort</servlet-name>
    		<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>MyWebServicePort</servlet-name>
    		<url-pattern>/</url-pattern>
    	</servlet-mapping>
    	<session-config>
    		<session-timeout>60</session-timeout>
    	</session-config>
    	<welcome-file-list>
    		<welcome-file>index.html</welcome-file>
    		<welcome-file>index.htm</welcome-file>
    		<welcome-file>index.jsp</welcome-file>
    		<welcome-file>default.html</welcome-file>
    		<welcome-file>default.htm</welcome-file>
    		<welcome-file>default.jsp</welcome-file>
    	</welcome-file-list>
    </web-app>
    

    Secure Web Service Implementation

    We use the same source files of JAX-WS and Secure Java Web Services using UsernameToken : WS-Security with Metro and WSIT example. But there are major policy changes in both server and client side WSIT Policy configuration files. The Java class changes are minor.
    Please ensure that the image download/upload methods are not ideal use cases for this example. You need to include MTOM to optimize (Read: Enable MTOM for JAX-WS Web Services) such methods.
    The web service level message/token encryption and decryption also requires keystores and digital certificates for server and client. The client should know the public key of Server. For this you need to export server’s digital certificate to client’s keystore. The server doesn’t require public key of client. These configurations are added as part of client and server WSIT policy configurations. The keystore location in these WSIT files can be absolute location or if no absolute location is provided the metro/wsit runtime will look for the keystore META-INF child directory of a directory in the classpath.
    For this example, we use the same keystore and digital certificates (self signed) which we used for JAX-WS Secure Web Services with Signatures and Encryption: WS-Security with Metro and WSIT example.

    Web Service SEI and Implementation and Password validator

    Let us create our SEI and implementation classes as well as our password validator class.
    The SEI and Implementation classes:

    /*
     * @(#)MyWebServiceIntf.java
     * @author Binu George
     * Globinch.com
     * copyright http://www.globinch.com. All rights reserved.
     */
    package com.globinch.service;
    
    import java.awt.Image;
    
    import javax.jws.WebMethod;
    import javax.jws.WebParam;
    import javax.jws.WebService;
    /**
     * The SEI
     * @author Binu George
     * @since 2013
     * @version 1.0
     */
    @WebService(name="MyWebService")
    public interface MyWebServiceIntf {
    
    	/**
    	 * Web service operation
    	 */
    	@WebMethod(operationName = "greetCustomer")
    	public String greetCustomer(@WebParam(name = "parameter") String parameter);
    
    	@WebMethod(operationName = "retrieveImage")
    	public Image retrieveImage(@WebParam(name = "name") String name);
    
    	@WebMethod(operationName = "uploadImage")
    	public String uploadImage(@WebParam(name = "file") Image file,
    			@WebParam(name = "name") String name);
    
    }
    
    /*
     * @(#)MyWebService.java
     * @author Binu George
     * Globinch.com
     * copyright http://www.globinch.com. All rights reserved.
     */
    package com.globinch.service;
    
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    import javax.jws.WebService;
    import javax.xml.ws.WebServiceException;
    
    /**
     * The web service implementation class.
     * @author Binu George
     * @since 2013
     * @version 1.0
     */
    @WebService()
    public class MyWebService implements MyWebServiceIntf {
    	 final static String PATH = "D:\\mtomtest\\upload\\";
    
        /* (non-Javadoc)
    	 * @see com.globinch.service.MyWebServiceIntf#greetCustomer(java.lang.String)
    	 */
        @Override
        public String greetCustomer(String parameter) {
            return "Hello..." + parameter;
        }
     	/* (non-Javadoc)
    	 * @see com.globinch.service.MyWebServiceIntf#retrieveImage(java.lang.String)
    	 */
     	@Override
    	public Image retrieveImage(String name) {
     		try {
    			// Create a file object with file name and read the image
    			File image = new File(PATH + name);
    			return ImageIO.read(image);
    		} catch (IOException e) {
    			e.printStackTrace();
    			throw new WebServiceException("Download Failed");
    		}
    	}
    	/* (non-Javadoc)
    	 * @see com.globinch.service.MyWebServiceIntf#uploadImage(java.awt.Image, java.lang.String)
    	 */
    	@Override
    	public String uploadImage(Image file, String name) {
    		if (file != null) {
    			try {
    				File image = new File(PATH + name);
    				ImageIO.write((BufferedImage) file, "jpg", image);
    			} catch (IOException e) {
    				e.printStackTrace();
    				throw new WebServiceException("Upload Failed");
    			}
    			return "Upload Successful";
    		}
    		throw new WebServiceException("No data to upload.");
    	}
    }
    

    The Password validator class:

    /*
     * @(#) MyServicePasswordValidator.java
     * @author Binu George
     * Globinch.com
     * copyright http://www.globinch.com. All rights reserved.
     */
    package com.globinch.service;
    
    import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
    import com.sun.xml.wss.impl.callback.PasswordValidationCallback.PasswordValidationException;
    /**
     * The plain text password validation class.
     * @author Binu George
     * @since 2013
     * @version 1.0
     */
    public class MyServicePasswordValidator implements PasswordValidationCallback.PasswordValidator {
    
    	public boolean validate(PasswordValidationCallback.Request pwdrequest) throws PasswordValidationCallback.PasswordValidationException {
    		if(pwdrequest instanceof PasswordValidationCallback.DigestPasswordRequest){
    			PasswordValidationCallback.DigestPasswordRequest request =
                    (PasswordValidationCallback.DigestPasswordRequest) pwdrequest;
    			
    			 if ("username".equals(request.getUsername())
    		                && "userpass".equals(request.getPassword())) {
    		            return true;
    		        }else{
    		        	throw new PasswordValidationCallback.PasswordValidationException("Error not valid");
    		        }
    		}
    		if(pwdrequest instanceof PasswordValidationCallback.PlainTextPasswordRequest){
    			 try {
    				return new PlainTextPasswordValidators().validate(pwdrequest);
    			} catch (PasswordValidationException e) {
    				e.printStackTrace();
    			}
    		}
    		return false;
           
        }
    
        /**
         * Plain text validator
         */
        private class PlainTextPasswordValidators implements PasswordValidationCallback.PasswordValidator {
    
            /**
             * Validate password
             * @param request
             * @return
             * @throws PasswordValidationCallback.PasswordValidationException
             */
            public boolean validate(PasswordValidationCallback.Request request)
                    throws PasswordValidationCallback.PasswordValidationException {
    
                PasswordValidationCallback.PlainTextPasswordRequest plainTextRequest =
                        (PasswordValidationCallback.PlainTextPasswordRequest) request;
    
                if ("username ".equals(plainTextRequest.getUsername())
    	                && "userpass".equals(plainTextRequest.getPassword())) {
    	            return true;
    	        } else{
    	        	throw new PasswordValidationCallback.PasswordValidationException("credentials  not valid");
    	        }
            }
        }
    
    }
    

    sun-jaxws.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- 
     The jax-ws xml configuration file for tomcat servlet container.
     www.Globinch.com
     -->
    <endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
        <endpoint name="MyWebService"
            implementation="com.globinch.service.MyWebService" 
            url-pattern="/"
            wsdl-location="WEB-INF/wsdl/MyWebServiceService.wsdl" enable-mtom="true">
        </endpoint>
    
    </endpoints>
    

    Service WSIT Policy Configuration For Secure UsernameToken Profile

    The major changes are in the WSIT server configuration file. We added all the policies required to sign and encrypt the username tokens. In this example the soap body and message will not be signed and encrypted.

    <?xml version="1.0" encoding="UTF-8"?>
    <definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
    	xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="MyWebServiceService"
    	targetNamespace="http://com.globinch.service/" 
    	xmlns:tns="http://com.globinch.service/"
    	xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" 
    	xmlns:wsp="http://www.w3.org/ns/ws-policy"
    	xmlns:wsp1="http://www.w3.org/ns/ws-policy"
    	xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
    	xmlns:wsaws="http://www.w3.org/2005/08/addressing" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy"
    	xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
    	<message name="uploadImage">
    		<part name="parameters" element="tns:uploadImage" />
    	</message>
    	<message name="uploadImageResponse">
    		<part name="parameters" element="tns:uploadImageResponse" />
    	</message>
    	<message name="greetCustomer">
    		<part name="parameters" element="tns:greetCustomer" />
    	</message>
    	<message name="greetCustomerResponse">
    		<part name="parameters" element="tns:greetCustomerResponse" />
    	</message>
    	<message name="retrieveImage">
    		<part name="parameters" element="tns:retrieveImage" />
    	</message>
    	<message name="retrieveImageResponse">
    		<part name="parameters" element="tns:retrieveImageResponse" />
    	</message>
    	<portType name="MyWebService">
    		<operation name="uploadImage">
    			<input wsam:Action="http://service.globinch.com/MyWebService/uploadImageRequest"
    				message="tns:uploadImage" />
    			<output
    				wsam:Action="http://service.globinch.com/MyWebService/uploadImageResponse"
    				message="tns:uploadImageResponse" />
    		</operation>
    		<operation name="greetCustomer">
    			<input
    				wsam:Action="http://service.globinch.com/MyWebService/greetCustomerRequest"
    				message="tns:greetCustomer" />
    			<output
    				wsam:Action="http://service.globinch.com/MyWebService/greetCustomerResponse"
    				message="tns:greetCustomerResponse" />
    		</operation>
    		<operation name="retrieveImage">
    			<input
    				wsam:Action="http://service.globinch.com/MyWebService/retrieveImageRequest"
    				message="tns:retrieveImage" />
    			<output
    				wsam:Action="http://service.globinch.com/MyWebService/retrieveImageResponse"
    				message="tns:retrieveImageResponse" />
    		</operation>
    	</portType>
    	<binding name="MyWebServicePortBinding" type="tns:MyWebService">
    		<wsp:PolicyReference URI="#MyWebServicePortBindingPolicy" />
    		<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
    			style="document" />
    		<operation name="uploadImage">
    			<soap:operation soapAction="" />
    			<input>
    				<wsp:PolicyReference URI="#MyWebServicePortBinding_Input_Policy"/>
    				<soap:body use="literal" />
    			</input>
    			<output>
    				<soap:body use="literal" />
    			</output>
    		</operation>
    		<operation name="greetCustomer">
    			<soap:operation soapAction="" />
    			<input>
    				<wsp:PolicyReference URI="#MyWebServicePortBinding_Input_Policy"/>
    				<soap:body use="literal" />
    			</input>
    			<output>
    				<soap:body use="literal" />
    			</output>
    		</operation>
    		<operation name="retrieveImage">
    			<soap:operation soapAction="" />
    			<input>
    				<wsp:PolicyReference URI="#MyWebServicePortBinding_Input_Policy"/>
    				<soap:body use="literal" />
    			</input>
    			<output>
    				<soap:body use="literal" />
    			</output>
    		</operation>
    	</binding>
    	<service name="MyWebServiceService">
    		<port name="MyWebServicePort" binding="tns:MyWebServicePortBinding" />
    	</service>
    	<wsp:Policy wsu:Id="MyWebServicePortBindingPolicy">
    		<wsp:ExactlyOne>
    		<wsp:All>
    		<wsam:Addressing wsp1:Optional="false"/>
    		  <sp:SymmetricBinding>
                        <wsp:Policy>
                            <sp:ProtectionToken>
                                <wsp:Policy>
                                    <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
                                        <wsp:Policy>
                                            <sp:WssX509V3Token10/>
                                            <sp:RequireIssuerSerialReference/>
                                        </wsp:Policy>
                                    </sp:X509Token>
                                </wsp:Policy>
                            </sp:ProtectionToken>
                            <sp:Layout>
                                <wsp:Policy>
                                    <sp:Strict/>
                                </wsp:Policy>
                            </sp:Layout>
                            <sp:IncludeTimestamp/>
                            <sp:OnlySignEntireHeadersAndBody/>
                            <sp:AlgorithmSuite>
                                <wsp:Policy>
                                    <sp:Basic128/>
                                </wsp:Policy>
                            </sp:AlgorithmSuite>
                        </wsp:Policy>
                    </sp:SymmetricBinding>
                     <sp:Wss11>
                        <wsp:Policy>
                            <sp:MustSupportRefIssuerSerial/>
                            <sp:MustSupportRefThumbprint/>
                            <sp:MustSupportRefEncryptedKey/>
                        </wsp:Policy>
                    </sp:Wss11>
    				<sp:SignedEncryptedSupportingTokens>
                        <wsp:Policy>
                            <sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                                <wsp:Policy>
                                    <sp:WssUsernameToken10/>
                                </wsp:Policy>
                            </sp:UsernameToken>
                        </wsp:Policy>
                    </sp:SignedEncryptedSupportingTokens
    <wsss:ValidatorConfiguration
    					wspp:visibility="private" xmlns:wsss="http://schemas.sun.com/2006/03/wss/server"
    					xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy">
    					<wsss:Validator name="usernameValidator"
    						classname="com.globinch.service. MyServicePasswordValidator” />
    				</wsss:ValidatorConfiguration>
    				<wsss:KeyStore alias="SERVER_KEY_ALIAS" 
              keypass="KEY_PASSWORD"
              location="SERVER_KEYSTORE_PATH" storepass="KEYSTORE_PASSWORD"
              xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy" wspp:visibility="private"
              xmlns:wsss="http://schemas.sun.com/2006/03/wss/server"/>
          			</wsp:All>
    		</wsp:ExactlyOne>
    	</wsp:Policy>
        <wsp:Policy wsu:Id="MyWebServicePortBinding_Input_Policy">
            <wsp:ExactlyOne>
                <wsp:All>
                    <sp:EncryptedSupportingTokens>
                        <wsp:Policy>
                            <sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                                <wsp:Policy>
                                    <sp:WssUsernameToken10/>
                                </wsp:Policy>
                            </sp:UsernameToken>
                        </wsp:Policy>
                    </sp:EncryptedSupportingTokens>
                </wsp:All>
            </wsp:ExactlyOne>
        </wsp:Policy>
    </definitions>
    

    Please note that we need to provide the keystore configuration in the WSIT server file. This is because the client certificate is imported into the server keystore. The server need client public key to decrypt the encrypted tokens.

  • Read : Quick look at Public-key cryptography
  • WSDL of Secure Signed and Encrypted UsernameToken MyService Service

    Once all the above are ready build your application and create war file named “MyService.war” Deploy it on tomcat. If it gets deployed successfully, you will see smilar to the ollowing message in the console.

    INFO: Deploying web application archive MyService.war
    May 19, 2013 12:25:37 PM com.sun.xml.ws.transport.http.servlet.WSServletContextListener contextInitialized
    INFO: WSSERVLET12: JAX-WS context listener initializing
    May 19, 2013 12:25:38 PM [com.sun.xml.ws.policy.parser.PolicyConfigParser]  parse
    INFO: WSP5018: Loaded WSIT configuration from file: jndi:/localhost/MyService/WEB-INF/wsit-com.globinch.service.MyWebService.xml.
    May 19, 2013 12:25:40 PM com.sun.xml.ws.server.MonitorBase createRoot
    INFO: Metro monitoring rootname successfully set to: com.sun.metro:pp=/,type=WSEndpoint,name=/MyService-MyWebServiceService-MyWebServicePort
    May 19, 2013 12:25:41 PM com.sun.xml.ws.transport.http.servlet.WSServletDelegate <init>
    INFO: WSSERVLET14: JAX-WS servlet initializing
    May 19, 2013 12:25:41 PM org.apache.coyote.http11.Http11Protocol start
    INFO: Starting Coyote HTTP/1.1 on http-8080
    May 19, 2013 12:25:41 PM org.apache.coyote.http11.Http11Protocol start
    INFO: Starting Coyote HTTP/1.1 on http-8443
    May 19, 2013 12:25:41 PM org.apache.jk.common.ChannelSocket init
    INFO: JK: ajp13 listening on /0.0.0.0:8009
    May 19, 2013 12:25:41 PM org.apache.jk.server.JkMain start
    INFO: Jk running ID=0 time=0/15  config=null
    May 19, 2013 12:25:41 PM org.apache.catalina.startup.Catalina start
    INFO: Server startup in 4284 ms
    

    Check the WSDL file by accessing https://YOUR_HOST_NAME:8443/MyService/?wsdl. See here the transport protocol is HTTPS not HTTP.
    The WSDL file

    <definitions
    		xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
    xmlns:wsp=http://www.w3.org/ns/ws-policy xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy"
    		xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
    xmlns:soap=http://schemas.xmlsoap.org/wsdl/soap/ xmlns:tns="http://service.globinch.com/"
    		xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/"
    		targetNamespace="http://service.globinch.com/" name="MyWebServiceService">
    		<wsp:Policy xmlns:wsapw3c="http://www.w3.org/2006/05/addressing/wsdl"
    		xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
    		xmlns:ssp="http://schemas.sun.com/2006/03/wss/server"
    xmlns:sunwsp=http://java.sun.com/xml/ns/wsit/policy wsu:Id="MyWebServicePortBindingPolicy">
    		<sp:SignedEncryptedSupportingTokens>
    			<wsp:Policy>
    				<sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
    				<wsp:Policy>
    					<sp:WssUsernameToken10 />
    						</wsp:Policy>
    							</sp:UsernameToken>
    						</wsp:Policy>
    		</sp:SignedEncryptedSupportingTokens>
    		<sp:TransportBinding>
    			<wsp:Policy>
    												<sp:AlgorithmSuite>
    													<wsp:Policy>
    														<sp:Basic128 />
    													</wsp:Policy>
    												</sp:AlgorithmSuite>
    												<sp:IncludeTimestamp />
    												<sp:Layout>
    													<wsp:Policy>
    														<sp:Lax />
    													</wsp:Policy>
    												</sp:Layout>
    												<sp:TransportToken>
    													<wsp:Policy>
    														<sp:HttpsToken RequireClientCertificate="false" />
    													</wsp:Policy>
    												</sp:TransportToken>
    											</wsp:Policy>
    										</sp:TransportBinding>
    										<wsapw3c:UsingAddressing />
    									</wsp:Policy>
    									<wsp:Policy
    										xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
    										wsu:Id="MyWebServicePortBinding_Input_Policy">
    										<sp:SignedEncryptedSupportingTokens>
    											<wsp:Policy>
    												<sp:UsernameToken
    													sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
    													<wsp:Policy>
    														<sp:WssUsernameToken10 />
    													</wsp:Policy>
    												</sp:UsernameToken>
    											</wsp:Policy>
    										</sp:SignedEncryptedSupportingTokens>
    									</wsp:Policy>
    									<types>
    										<xsd:schema>
    											<xsd:import namespace="http://service.globinch.com/"
    												schemaLocation="https://localhost:8443/MyService/?xsd=1" />
    										</xsd:schema>
    									</types>
    									<message name="uploadImage">
    										<part name="parameters" element="tns:uploadImage" />
    									</message>
    									<message name="uploadImageResponse">
    										<part name="parameters" element="tns:uploadImageResponse" />
    									</message>
    									<message name="greetCustomer">
    										<part name="parameters" element="tns:greetCustomer" />
    									</message>
    									<message name="greetCustomerResponse">
    										<part name="parameters" element="tns:greetCustomerResponse" />
    									</message>
    									<message name="retrieveImage">
    										<part name="parameters" element="tns:retrieveImage" />
    									</message>
    									<message name="retrieveImageResponse">
    										<part name="parameters" element="tns:retrieveImageResponse" />
    									</message>
    									<portType name="MyWebService">
    										<operation name="uploadImage">
    											<input
    												wsam:Action="http://service.globinch.com/MyWebService/uploadImageRequest"
    												message="tns:uploadImage" />
    											<output
    												wsam:Action="http://service.globinch.com/MyWebService/uploadImageResponse"
    												message="tns:uploadImageResponse" />
    										</operation>
    										<operation name="greetCustomer">
    											<input
    												wsam:Action="http://service.globinch.com/MyWebService/greetCustomerRequest"
    												message="tns:greetCustomer" />
    											<output
    												wsam:Action="http://service.globinch.com/MyWebService/greetCustomerResponse"
    												message="tns:greetCustomerResponse" />
    										</operation>
    										<operation name="retrieveImage">
    											<input
    												wsam:Action="http://service.globinch.com/MyWebService/retrieveImageRequest"
    												message="tns:retrieveImage" />
    											<output
    												wsam:Action="http://service.globinch.com/MyWebService/retrieveImageResponse"
    												message="tns:retrieveImageResponse" />
    										</operation>
    									</portType>
    									<binding name="MyWebServicePortBinding" type="tns:MyWebService">
    										<wsp:PolicyReference
    											URI="#MyWebServicePortBinding_MTOM_Policy-MyWebServicePortBinding_MTOM_Policy" />
    										<wsp:PolicyReference URI="#MyWebServicePortBindingPolicy" />
    										<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
    											style="document" />
    										<operation name="uploadImage">
    											<soap:operation soapAction="" />
    											<input>
    												<wsp:PolicyReference URI="#MyWebServicePortBinding_Input_Policy" />
    												<soap:body use="literal" />
    											</input>
    											<output>
    												<soap:body use="literal" />
    											</output>
    										</operation>
    										<operation name="greetCustomer">
    											<soap:operation soapAction="" />
    											<input>
    												<wsp:PolicyReference URI="#MyWebServicePortBinding_Input_Policy" />
    												<soap:body use="literal" />
    											</input>
    											<output>
    												<soap:body use="literal" />
    											</output>
    										</operation>
    										<operation name="retrieveImage">
    											<soap:operation soapAction="" />
    											<input>
    												<wsp:PolicyReference URI="#MyWebServicePortBinding_Input_Policy" />
    												<soap:body use="literal" />
    											</input>
    											<output>
    												<soap:body use="literal" />
    											</output>
    										</operation>
    									</binding>
    									<service name="MyWebServiceService">
    										<port name="MyWebServicePort" binding="tns:MyWebServicePortBinding">
    											<soap:address location="https://localhost:8443/MyService/" />
    										</port>
    									</service>
    								</definitions>
    
    

    Secure Web Service “MyService” Client with Signed and Encrypted UsernameToken

    Secure Web Service Client application that signs and encrypts UsernameToken and use Transport Layer Security (TLS/SSL) and HTTPS to communicate with service producer.
    When you create JAX-WS client application using metro you need to have the following files.

    • The service proxy classes
    • {wsdl file name}.xml
    • wsit-client.xml
    • Service client classes.
    • CallbackHandler class.
    • The client keystore/digital certificates

    Now we need to setup our client application. Here also we will use the same example we used for JAX-WS and Secure Java Web Services using UsernameToken : WS-Security with Metro and WSIT
    Here also the major change is in the client WSIT configuration file. We need to add the relevant changes to the file to support signing and encryption if usernametoken.

    The Service Consumer class

    The first step in creating the web service client is to generate the proxy artifacts using wsimport utility.

    wsimport -keep -XadditionalHeaders http://localhost:8080/MyService/?wsdl
    

    Using the proxy stub classes you can create Service Consumer Client class for our secure, signed and encrtpted UsernameToken Web Service.

    The Service Consumer class

    The service client class file.

    /*
     * @(#)Client.java
     * @author Binu George
     * Globinch.com
     * copyright http://www.globinch.com. All rights reserved.
     */
    package com.globinch.client;
    
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.Map;
    
    import javax.imageio.ImageIO;
    import javax.xml.namespace.QName;
    import javax.xml.ws.BindingProvider;
    import javax.xml.ws.Service;
    
    import com.globinch.service.MyWebService;
    /**
     * The web service client service invoker class.
     * @author Binu George
     * @since 2013
     * @version 1.0
     */
    public class Client {
            private static URL url = null;
    	private static Service service = null;
    	private static final String PATH = "D:\\mtomtest\\download\\";
    	public Client() {
    		try {
    			url = new URL("https://localhost:8443/MyService/?wsdl");
    			QName qname = new QName("http://service.globinch.com/",
    					"MyWebServiceService");
    			service = Service.create(url, qname);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    	}
    
    	/**
    	 * Upload image
    	 * @return String
    	 */
    	public String uploadImage() {
    		try {
    			MyWebService myService = service.getPort(MyWebService.class);
    	
    			File file = new File(PATH + "11841.jpg");
    			BufferedImage imageToUpload = null;
    
    			try {
    				imageToUpload = ImageIO.read(file);
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			double d = Math.random();
    			byte[] imageInByte = null;
    			try {
    				ByteArrayOutputStream baos = new ByteArrayOutputStream();
    				ImageIO.write(imageToUpload, "jpg", baos);
    				baos.flush();
    				imageInByte = baos.toByteArray();
    				baos.close();
    
    			} catch (IOException e) {
    				System.out.println(e.getMessage());
    			}
    			// now upload the image
    			myService.uploadImage(imageInByte, "ImageFromClient" + d + ".jpg");
    			String imageToDownload = d + "";
    			return imageToDownload;
    		} catch (Exception e) {
    
    			e.printStackTrace();
    		}
    		return null;
    	}
    	/**
    	 * Download the uploaded image
    	 * @param imageName
    	 * @return String
    	 */
    	public String downloadImage(String imageName) {
    		try {
    
    			MyWebService myService = service.getPort(MyWebService.class);
    
    			// lets now download the uploaded image
    			byte[] downloadedImage = myService
    					.retrieveImage("ImageFromClient" + imageName + ".jpg");
    			File imageFromServer = new File(PATH + "ImageFromServer"
    					+ imageName + ".jpg");
    
    			try {
    				FileOutputStream fileOuputStream = new FileOutputStream(
    						imageFromServer);
    				fileOuputStream.write(downloadedImage);
    				fileOuputStream.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    			return "success";
    		} catch (Exception e) {
    
    			e.printStackTrace();
    		}
    		return null;
    
    	}
    	/**
    	 * Greet the customer
    	 * @param name
    	 * @return String
    	 */
    	public String greet(String name) {
    		try {
    			MyWebService myService = service.getPort(MyWebService.class);
    			String message = myService.greetCustomer(name);
    			System.out.println(message);
    			return message;
    
    		} catch (Exception exception) {
    			exception.printStackTrace();
    		}
    		return "empty string";
    	}
    
    	public static void main(String[] args) {
    
    		try {
    			new Client().greet("Some user");
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }
    

    The Callbackhandler class

    /*
     * @(#)MyCallbackHandler.java
     * @author Binu George
     * Globinch.com
     * copyright http://www.globinch.com. All rights reserved.
     */
    package com.globinch.client;
    
    import java.io.IOException;
    
    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.callback.NameCallback;
    import javax.security.auth.callback.PasswordCallback;
    import javax.security.auth.callback.UnsupportedCallbackException;
    
    import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
    
    /**
     * The callback handler class to manage username and password.
     * @author Binu George
     * @since 2013
     * @version 1.0
     */
    public class MyCallbackHandler implements CallbackHandler {
    	   
    	
    	public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
            	for (Callback callback : callbacks) {
                      if (callback instanceof NameCallback) {
                	 	NameCallback nc = (NameCallback) callback;
    	               nc.setName("username");
    	              
                		} else if (callback instanceof PasswordCallback) {
                	 		PasswordCallback pc = (PasswordCallback) callback;
    	               	pc.setPassword("userpass".toCharArray());
    	  
                		} else {
                    		throw new UnsupportedCallbackException(callback,   "Unrecognized Callback");
                		}
            	}
        	}
    }
    

    The WSIT Client Configuration files for Signed and Encrypted UsernameToken Profile

    <?xml version="1.0" encoding="UTF-8"?>
    <definitions
      xmlns="http://schemas.xmlsoap.org/wsdl/"
      xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="mainclientconfig">
      <import location="MyWebServiceService.xml" namespace="http://service.globinch.com/"/>
    </definitions>
    

    The client policy configuration file. (MyWebServiceService.xml).

    <?xml version="1.0" encoding="UTF-8"?> 
    <definitions
    	xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
    	xmlns:wsp="http://www.w3.org/ns/ws-policy" 
    	xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" 
    	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    	xmlns:tns="http://service.globinch.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    	xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://service.globinch.com/"
    	xmlns:sc="http://schemas.sun.com/2006/03/wss/client"
    	xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy"
    	xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
    	xmlns:wsp1="http://www.w3.org/ns/ws-policy"
    	name="MyWebServiceService">
    	
    	<wsp:Policy wsu:Id="MyWebServicePortBindingPolicy">
    		<wsp:ExactlyOne>
    			<wsp:All>
    				<wsam:Addressing wsp1:Optional="false"/>
    				 <sp:SymmetricBinding>
                        <wsp:Policy>
                            <sp:ProtectionToken>
                                <wsp:Policy>
                                    <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
                                        <wsp:Policy>
                                            <sp:WssX509V3Token10/>
                                            <sp:RequireIssuerSerialReference/>
                                        </wsp:Policy>
                                    </sp:X509Token>
                                </wsp:Policy>
                            </sp:ProtectionToken>
                            <sp:Layout>
                                <wsp:Policy>
                                    <sp:Strict/>
                                </wsp:Policy>
                            </sp:Layout>
                            <sp:IncludeTimestamp/>
                            <sp:OnlySignEntireHeadersAndBody/>
                            <sp:AlgorithmSuite>
                                <wsp:Policy>
                                    <sp:Basic128/>
                                </wsp:Policy>
                            </sp:AlgorithmSuite>
                        </wsp:Policy>
                    </sp:SymmetricBinding>
                     <sp:Wss11>
                        <wsp:Policy>
                            <sp:MustSupportRefIssuerSerial/>
                            <sp:MustSupportRefThumbprint/>
                            <sp:MustSupportRefEncryptedKey/>
                        </wsp:Policy>
                    </sp:Wss11>
    				<sp:SignedEncryptedSupportingTokens>
                        <wsp:Policy>
                            <sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                                <wsp:Policy>
                                    <sp:WssUsernameToken10/>
                                </wsp:Policy>
                            </sp:UsernameToken>
                        </wsp:Policy>
                    </sp:SignedEncryptedSupportingTokens
    <sc:CallbackHandlerConfiguration wspp:visibility="private">
              <sc:CallbackHandler classname="com.globinch.client.MyCallbackHandler" name="usernameHandler"/>
              <sc:CallbackHandler classname="com.globinch.client.MyCallbackHandler" name="passwordHandler"/>
            </sc:CallbackHandlerConfiguration>
             <sc:KeyStore wspp:visibility="private" location="PATH_TO_YOUR_KEYSTORE_FILE"
                storepass="KEYSTORE_PASSWORD" alias="CLIENT_KEY_ALIAS_NAME" keypass="KEY_PASSWORD"/>
            <sc:TrustStore wspp:visibility="private" location="PATH_TO_YOUR_CLIENT_KEYSTORE_FILE"
                storepass="KEYSTORE_PASSWORD" peeralias="SERVER_KEY_ALIAS"/>
        		</wsp:All>
    		</wsp:ExactlyOne>
    	</wsp:Policy>
         <wsp:Policy wsu:Id="MyWebServicePortBinding_Input_Policy">
            <wsp:ExactlyOne>
                <wsp:All>
                    <sp:EncryptedSupportingTokens>
                        <wsp:Policy>
                            <sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                                <wsp:Policy>
                                    <sp:WssUsernameToken10/>
                                </wsp:Policy>
                            </sp:UsernameToken>
                        </wsp:Policy>
                    </sp:EncryptedSupportingTokens>
                </wsp:All>
            </wsp:ExactlyOne>
        </wsp:Policy>
    	<types>
    		<xsd:schema>
    			<xsd:import namespace="http://service.globinch.com/"
    				schemaLocation="http://localhost:8080/MyService/?xsd=1" />
    		</xsd:schema>
    	</types>
    	<message name="uploadImage">
    		<part name="parameters" element="tns:uploadImage" />
    	</message>
    	<message name="uploadImageResponse">
    		<part name="parameters" element="tns:uploadImageResponse" />
    	</message>
    	<message name="greetCustomer">
    		<part name="parameters" element="tns:greetCustomer" />
    	</message>
    	<message name="greetCustomerResponse">
    		<part name="parameters" element="tns:greetCustomerResponse" />
    	</message>
    	<message name="retrieveImage">
    		<part name="parameters" element="tns:retrieveImage" />
    	</message>
    	<message name="retrieveImageResponse">
    		<part name="parameters" element="tns:retrieveImageResponse" />
    	</message>
    	<portType name="MyWebService">
    		<operation name="uploadImage">
    			<input wsam:Action="http://service.globinch.com/MyWebService/uploadImageRequest"
    				message="tns:uploadImage" />
    			<output
    				wsam:Action="http://service.globinch.com/MyWebService/uploadImageResponse"
    				message="tns:uploadImageResponse" />
    		</operation>
    		<operation name="greetCustomer">
    			<input
    				wsam:Action="http://service.globinch.com/MyWebService/greetCustomerRequest"
    				message="tns:greetCustomer" />
    			<output
    				wsam:Action="http://service.globinch.com/MyWebService/greetCustomerResponse"
    				message="tns:greetCustomerResponse" />
    		</operation>
    		<operation name="retrieveImage">
    			<input
    				wsam:Action="http://service.globinch.com/MyWebService/retrieveImageRequest"
    				message="tns:retrieveImage" />
    			<output
    				wsam:Action="http://service.globinch.com/MyWebService/retrieveImageResponse"
    				message="tns:retrieveImageResponse" />
    		</operation>
    	</portType>
    	<binding name="MyWebServicePortBinding" type="tns:MyWebService">
    		<wsp:PolicyReference URI="#MyWebServicePortBindingPolicy" />
    		<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
    			style="document" />
    		<operation name="uploadImage">
    			<soap:operation soapAction="" />
    			<input>
    			<wsp:PolicyReference URI="#MyWebServicePortBinding_Input_Policy"/>
    				<soap:body use="literal" />
    			</input>
    			<output>
    				<soap:body use="literal" />
    			</output>
    		</operation>
    		<operation name="greetCustomer">
    			<soap:operation soapAction="" />
    			<input>
    			<wsp:PolicyReference URI="#MyWebServicePortBinding_Input_Policy"/>
    				<soap:body use="literal" />
    			</input>
    			<output>
    				<soap:body use="literal" />
    			</output>
    		</operation>
    		<operation name="retrieveImage">
    			<soap:operation soapAction="" />
    			<input>
    			<wsp:PolicyReference URI="#MyWebServicePortBinding_Input_Policy"/>
    				<soap:body use="literal" />
    			</input>
    			<output>
    				<soap:body use="literal" />
    			</output>
    		</operation>
    	</binding>
    	<service name="MyWebServiceService">
    		<port name="MyWebServicePort" binding="tns:MyWebServicePortBinding">
    			<soap:address location="http://localhost:8080/MyService/" />
    		</port>
    	</service>
    </definitions>
    

    Utility Servlet Web Component

    We use a utility servlet class, which invokes the service client methods. You can create appropriate JSP/JSF or UI file to invoke the servlet method.
    MyServiceServlet class.

    /*
     * @(#)MyServiceServlet.java
     * @author Binu George
     * Globinch.com
     * copyright http://www.globinch.com. All rights reserved.
     */
    package com.globinch.client;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    /**
     * Servlet implementation class MyServiceServlet
     * 
     * @author Binu George
     * @since 2013
     * @version 1.0
      */
    public class MyServiceServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
    
    	/**
    	 * @see HttpServlet#HttpServlet()
    	 */
    	public MyServiceServlet() {
    		super();
    }
    
    	/**
    	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
    	 *      response)
    	 */
    	protected void doGet(HttpServletRequest request,
    			HttpServletResponse response) throws ServletException, IOException {
    }
    
    	/**
    	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
    	 *      response)
    	 */
    	protected void doPost(HttpServletRequest request,
    			HttpServletResponse response) throws ServletException, IOException {
    		Client service = new Client();
    		if (request.getParameter("UploadImage") != null) {
    			String imageName = service.uploadImage();
    
    			HttpSession httpSession = request.getSession();
    			httpSession.setAttribute("IMAGE", imageName);
    			PrintWriter out = response.getWriter();
    			out.println("<br/>");
    			out.println("<br/>");
    			out.println("<br/>");
    			out
    					.println("The image is uploaded. The image name =ImageFromClient"
    							+ imageName + ".jpg");
    			out.println("<br/>");
    			out.println("<br/>");
    			out
    					.println("Please choose another action from <a href=\"index.jsp\">Home Page</a>");
    		} else if (request.getParameter("DownloadImage") != null) {
    			HttpSession httpSession = request.getSession();
    			String imageName = (String) httpSession.getAttribute("IMAGE");
    			PrintWriter out = response.getWriter();
    			if (imageName == null || imageName.isEmpty()) {
    				out.println("<br/>");
    				out
    						.println("Please upload an image first to download it. Try from <a href=\"index.jsp\">Home Page</a>");
    			} else {
    				String message = service.downloadImage(imageName);
    
    				out.println("<br/>");
    				out.println("<br/>");
    				out.println("<br/>");
    				out.println("The download of image ImageFromClient" + imageName
    						+ ".jpg is " + message);
    				out.println("<br/>");
    				out.println("<br/>");
    				out
    						.println("Please choose another action from <a href=\"index.jsp\">Home Page</a>");
    			}
    		} else if (request.getParameter("GreetMe") != null) {
    			String message = service.greet("Friend");
    			PrintWriter out = response.getWriter();
    			out.println("<br/>");
    			out.println("<br/>");
    			out.println("<br/>");
    			out.println(message);
    			out.println("<br/>");
    			out.println("<br/>");
    			out
    					.println("Please choose another action from <a href=\"index.jsp\">Home Page</a>");
    		} else {
    			PrintWriter out = response.getWriter();
    			out.println("<br/>");
    			out.println("<br/>");
    			out
    					.println("Wrong Action. Please choose an action from <a href=\"index.jsp\">Home Page</a>");
    			out.println("<br/>");
    			out.println("<br/>");
    		}
    
    	}
    
    }
    

    Web.xml

    Since we deploy this clinet application as a web archive on tomcat, we need to configure the web.xml to support HTTPS.

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
      <display-name> MyServiceClient</display-name>
      <security-constraint>
        <web-resource-collection>
            <web-resource-name>MyServiceClient</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
      <servlet>
        <description></description>
        <display-name>MyServiceServlet</display-name>
        <servlet-name>MyServiceServlet</servlet-name>
        <servlet-class>com.globinch.client.MyServiceServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>MyServiceServlet</servlet-name>
        <url-pattern>/MyServiceServlet</url-pattern>
      </servlet-mapping>
    </web-app>
    

    The Request and Response samples

    You can run the clinet application and check the request and responses. A sample request response pair is given below for greetCustomer service operation.
    Sample Request

    ---[HTTP request - https://localhost:8443/MyService/]---
    Accept:
    text/xml, multipart/related
    Content-Type: multipart/related;start="
    <rootpart * b8717-54f4-4981-8eb9-aa683b07ef52 @
    	example.jaxws.sun.com>
    	";type="application/xop+xml";boundary="uuid:560b8717-54f4-4981-8eb9-aa683b07ef52";start-info="text/xml"
    	SOAPAction:
    	"http://service.globinch.com/MyWebService/greetCustomerRequest"
    	User-Agent: Metro/2.2.1-1 (tags/2.2.1-1-7267; 2012-08-30T14:04:51+0000)
    	JAXWS-RI/2.2.7 JAXWS/2.2 svn-revision#unknown
    	--uuid:560b8717-54f4-4981-8eb9-aa683b07ef52
    	Content-Id:
    	<rootpart * b8717-54f4-4981-8eb9-aa683b07ef52 @
    		example.jaxws.sun.com>
    		Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
    		Content-Transfer-Encoding: binary
    
    <?xml version='1.0' encoding='UTF-8'?>
    		<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
    			xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
    			xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    			xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
    			xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
    			xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:exc14n="http://www.w3.org/2001/10/xml-exc-c14n#">
    			<S:Header>
    				<To xmlns="http://www.w3.org/2005/08/addressing">https://localhost:8443/MyService/</To>
    				<Action xmlns="http://www.w3.org/2005/08/addressing" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
    					S:mustUnderstand="1">http://service.globinch.com/MyWebService/greetCustomerRequest</Action>
    				<ReplyTo xmlns="http://www.w3.org/2005/08/addressing">
    					<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
    				</ReplyTo>
    				<FaultTo xmlns="http://www.w3.org/2005/08/addressing">
    					<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
    				</FaultTo>
    				<MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:578e1be1-7139-4ee5-a897-f429a668482d</MessageID>
    				<wsse:Security S:mustUnderstand="1">
    					<wsu:Timestamp
    						xmlns:ns18="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"
    						xmlns:ns17="http://www.w3.org/2003/05/soap-envelope" wsu:Id="_3">
    						<wsu:Created>2013-05-19T08:55:20Z</wsu:Created>
    						<wsu:Expires>2013-05-19T09:00:20Z</wsu:Expires>
    					</wsu:Timestamp>
    					<xenc:EncryptedKey
    						xmlns:ns18="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"
    						xmlns:ns17="http://www.w3.org/2003/05/soap-envelope" Id="_5002">
    						<xenc:EncryptionMethod
    							Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" />
    						<ds:KeyInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    							xsi:type="KeyInfoType">
    							<wsse:SecurityTokenReference>
    								<ds:X509Data>
    									<ds:X509IssuerSerial>
    										<ds:X509IssuerName>CN=localhost, OU=home, O=home, L=city,
    											ST=state, C=in</ds:X509IssuerName>
    										<ds:X509SerialNumber>173056135</ds:X509SerialNumber>
    									</ds:X509IssuerSerial>
    								</ds:X509Data>
    							</wsse:SecurityTokenReference>
    						</ds:KeyInfo>
    						<xenc:CipherData>
    							<xenc:CipherValue xmlns:xop="http://www.w3.org/2004/08/xop/include">
    								<xop:Include	href="cid:81ce4f87-fb39-404e-990e-d1eb8aa89e79@example.jaxws.sun.com" />
    							</xenc:CipherValue>
    						</xenc:CipherData>
    					</xenc:EncryptedKey>
    					<xenc:ReferenceList
    						xmlns:ns18="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"
    						xmlns:ns17="http://www.w3.org/2003/05/soap-envelope">
    						<xenc:DataReference URI="#_5003" />
    						<xenc:DataReference URI="#_5004" />
    					</xenc:ReferenceList>
    					<xenc:EncryptedData
    						xmlns:ns18="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"
    						xmlns:ns17="http://www.w3.org/2003/05/soap-envelope" Id="_5004"
    						Type="http://www.w3.org/2001/04/xmlenc#Element">
    						<xenc:EncryptionMethod
    							Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
    						<ds:KeyInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    							xsi:type="KeyInfoType">
    							<wsse:SecurityTokenRe ference
    								wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
    								<wsse:Reference URI="#_5002"
    									ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey" />
    							</wsse:SecurityTokenReference>
    						</ds:KeyInfo>
    						<xenc:CipherData>
    							<xenc:CipherValue xmlns:xop="http://www.w3.org/2004/08/xop/include">
    								<xop:Include
    									href="cid:04fdd703-789b-4138-b8b6-064740838730@example.jaxws.sun.com" />
    							</xenc:CipherValue>
    						</xenc:CipherData>
    					</xenc:EncryptedData>
    					<xenc:EncryptedData
    						xmlns:ns18="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"
    						xmlns:ns17="http://www.w3.org/2003/05/soap-envelope" Id="_5003"
    						Type="http://www.w3.org/2001/04/xmlenc#Element">
    						<xenc:EncryptionMethod
    							Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
    						<ds:KeyInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    							xsi:type="KeyInfoType">
    							<wsse:SecurityTokenReference
    								wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
    								<wsse:Reference URI="#_5002"
    									ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey" />
    							</wsse:SecurityTokenReference>
    						</ds:KeyInfo>
    						<xenc:CipherData>
    							<xenc:CipherValue xmlns:xop="http://www.w3.org/2004/08/xop/include">
    								<xop:Include
    									href="cid:ef07d044-d96b-4539-98ef-573fed8e4528@example.jaxws.sun.com" />
    							</xenc:CipherValue>
    						</xenc:CipherData>
    					</xenc:EncryptedData>
    					<ds:Signature
    						xmlns:ns18="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"
    						xmlns:ns17="http://www.w3.org/2003/05/soap-envelope" Id="_1">
    						<ds:SignedInfo>
    							<ds:CanonicalizationMethod
    								Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
    								<exc14n:InclusiveNamespaces
    									PrefixList="wsse S" />
    							</ds:CanonicalizationMethod>
    							<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1" />
    							<ds:Reference URI="#_3">
    								<ds:Transforms>
    									<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
    										<exc14n:InclusiveNamespaces
    											PrefixList="wsu wsse S" />
    									</ds:Transform>
    								</ds:Transforms>
    								<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
    								<ds:DigestValue>ar+A98WXKJVoIWOLSGUzr3X/W0Y=</ds:DigestValue>
    							</ds:Reference>
    							<ds:Reference URI="#uuid_e940023f-324e-4753-ae91-9b2471d35700">
    								<ds:Transforms>
    									<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
    										<exc14n:InclusiveNamespaces
    											PrefixList="wsu wsse S" />
    									</ds:Transform>
    								</ds:Transforms>
    								<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
    								<ds:DigestValue>tn1vzElwtkLW03qv9KFS+sdfEag=</ds:DigestValue>
    							</ds:Reference>
    						</ds:SignedInfo>
    						<ds:SignatureValue>2B7xG6PH/T4ZMHWZuQV7ZUHnQqc=</ds:SignatureValue>
    						<ds:KeyInfo>
    							<wsse:SecurityTokenReference
    								wsu:Id="uuid_25f07f55-e40f-4d0f-b8ad-ab782119aa85"
    								wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
    								<wsse:Reference URI="#_5002"
    									ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey" />
    							</wsse:SecurityTokenReference>
    						</ds:KeyInfo>
    					</ds:Signature>
    				</wsse:Security>
    			</S:Header>
    			<S:Body>
    				<ns2:greetCustomer xmlns:ns2="http://service.globinch.com/">
    					<arg0>Friend</arg0>
    				</ns2:greetCustomer>
    			</S:Body>
    		</S:Envelope>
    		--uuid:560b8717-54f4-4981-8eb9-aa683b07ef52
    		Content-Id: <81ce4f87-fb39-404e-990e-d1eb8aa89e79@example.jaxws.sun.com>
    		Content-Type: application/ciphervalue
    		Content-Transfer-Encoding: binary
    
    		ktΣ♫╠╔ê-a3f?ñ═O═å┤9╣¡↕≡lô?‼α≈CTD║)⌠→  ∙û%╕q]TêÄö∩Æ╩↓ƒT£6Mxï
    		?_+♦Aj}O(φ?╓ÿ√`7ML☻f╦½√∟ªº÷ú↑T↓Ä▲ñv▬≤S\≥σz‼⌂╧♣#∞ßB&└²╫sÿ╪■╚*µ
    		Γ↕▼☼í╖∩╫╚≈K]╧ö+╙k♫┤m
    		--uuid:560b8717-54f4-4981-8eb9-aa683b07ef52
    		Content-Id: <04fdd703-789b-4138-b8b6-064740838730@example.jaxws.sun.com>
    		Content-Type: application/ciphervalue
    		Content-Transfer-Encoding: binary
    
    		A♀/┼C§♫▲GO½|¼&╦ê█╪O¢X↔£┼«8â]½╠d╘░rbï=■┤║⌂♥jUêTàµ≈τB-┌╖û╜5_♥╡÷└íTπ≡α║≥√┐Äeú┘∟]úY∙πºQ╖↑J╙¿≡¢0φ!±SF╧ç•Σm↑☼7r∩«ⁿu6?─▄U¿░?eæD☻ç
    		╡‼ÑÖ╪%P►öY§3░╣l▒múc☺j╪♥┘τ║⌠♀&░ê╙╣σæ%⌡╘╧}l3?k╠O4>♣?k¼ûΦ╙~5↨ö•┐5@£K♫vP¿↨÷n│@²ºf¬ç╞√Ü♂▌?4C╣c♀H@⌂┤}δ^εr:☻|?-f ª╤░°₧9}Ñ┬%|≥4░─├♠▲ù┴}☻Ü╛P@Hí9ÜWEB&╗≤┴ê╝é┘├
    		ú0▌└|%╣aéε°♀╬ⁿ⌂╕╡╡b)ƒk6häcΓ▒è£☼s▓(,╙╬ ╝☺!▐┴σ║%p♥º⌐m│≥|ího
    		`█♫└
    		↔íSÇ█╪♂┐┴▲▀Γ)(6╗"s╛=│╦6¿¬âτ▒╗dOxù╩≈⌠∞F‼P┘Ö^Vÿô≥╤┌"▀?╠µXQ╚▄╚Ü╚¼b↨£≈sΓ┴K~Ç$30s▐kò}5≥4»±╝ö4å?bD@rÑ╗╡ò]δ¬1Jur╗µ?íl■í!w¶├ë⌐l*σz
    		Ω±?₧å½öwñG.←5╕<♠òτ¬₧
    		--uuid:560b8717-54f4-4981-8eb9-aa683b07ef52
    		Content-Id:
    		<ef07d044-d96b-4539-98ef-573fed8e4528 @
    			example.jaxws.sun.com>
    			Content-Type: application/ciphervalue
    			Content-Transfer-Encoding: binary
    
    			ê∟╙H↔'┐█oZ1┐_¼☺\V!╕Q─,0öi_í1c/
    			<pë ⌡ ó   è ┘ ä ° T ≤ ûα ▼ U ↕ â3Γ ? G º Rï ╞ α ╩ φZP6 ↓ í ‼ α │ Ω »
    				g ╧ ô ] δ ] Θ ╩ QaD ┴ a ╤ p ╕ τó ╕ ÿW ≈ Ä ) E → X ╫ úè ┴ T \ gVGs →
    				û ║ æà A- ─ d8pu ╡ ú6 ╓ eä ♀ φ & çtW µ>
    				w▲ ╠←╤φΓëê3Σe╣╝?φçâH$♠«á≈3,¡⌠ùO§¢òû=╓☼☺☼╨⌐¶╤
    				(-]¼τ╙╣←$└]╛{AèÖ¿
    				ë╠a├R←ï│↨+←ëC‼ò┬♥░▄«ë½Γ*↓&╚Φ╢▓◄²J4TσH7â╕2?•│êJ╠>Ü,τí╒Æh↕;HÖù:pHΦ0╪α╜¶Nx♫└gGº7±:k█:∙▀Vî-x?#à⌠uÑ♫☺à╣±FΦΣ╓è╠2Öû═Γα┌←_pq9▒╚ïd&
    				♀]W♂!ⁿ╧♠º18♀ï«ò╚▌▼↨Ωiπ²▒|e↑♥WU╪↓♀[?↨☻♦!☺(ⁿ╖Ω‼╞└|╘H╗÷t^ⁿX░s▀Ö╩^♫╚4m@∙▀▀ΓZµj]ª╣£╘-⌡φ
    				┐b|∟VU
    				--uuid:560b8717-54f4-4981-8eb9-aa683b07ef52----------------------
    

    Sample Response:

    ---[HTTP response - https://localhost:8443/MyService/ - 200]---
    				null: HTTP/1.1 200 OK
    				Content-Type: multipart/related;start="
    				<rootpart * bd210aea-ae7f-4bc2-8da8-800c509204ba @
    					example.jaxws.sun.com>
    					";type="application/xop+xml";boundary="uuid:bd210aea-ae7f-4bc2-8da8-800c509204ba";start-info="text/xml"
    					Date: Sun, 19 May 2013 08:55:21 GMT
    					Server: Apache-Coyote/1.1
    					Transfer-Encoding: chunked
    					--uuid:bd210aea-ae7f-4bc2-8da8-800c509204ba
    					Content-Id:
    					<rootpart * bd210aea-ae7f-4bc2-8da8-800c509204ba @
    						example.jaxws.sun.com>
    						Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
    						Content-Transfer-Encoding: binary
    
    <?xml version='1.0' encoding='UTF-8'?>
    						<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
    							xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
    							xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    							xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
    							xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
    							xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:exc14n="http://www.w3.org/2001/10/xml-exc-c14n#">
    							<S:Header>
    								<Action xmlns="http://www.w3.org/2005/08/addressing"
    									xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
    									S:mustUnderstand="1">http://service.globinch.com/MyWebService/greetCustomerResponse</Action>
    								<MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:19e5dd46-7c00-49d0-b8d9-48577af3de24</MessageID>
    								<RelatesTo xmlns="http://www.w3.org/2005/08/addressing">uuid:578e1be1-7139-4ee5-a897-f429a668482d</RelatesTo>
    								<To xmlns="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/anonymo
    									us</To>
    								<wsse:Security S:mustUnderstand="1">
    									<wsu:Timestamp
    										xmlns:ns18="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"
    										xmlns:ns17="http://www.w3.org/2003/05/soap-envelope" wsu:Id="_3">
    										<wsu:Created>2013-05-19T08:55:21Z</wsu:Created>
    										<wsu:Expires>2013-05-19T09
    											:00:21Z</wsu:Expires>
    									</wsu:Timestamp>
    									<ds:Signature
    										xmlns:ns18="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512"
    										xmlns:ns17="http://www.w3.org/2003/05/soap-envelope" Id="_1">
    										<ds:SignedInfo>
    											<ds:CanonicalizationMethod
    												Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
    												<exc14n:InclusiveNamespaces
    													PrefixList="wsse S" />
    											</ds:CanonicalizationMethod>
    											<ds:SignatureMethod
    												Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1" />
    											<ds:Reference URI="#_3">
    												<ds:Transforms>
    													<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
    														<e xc14n:InclusiveNamespaces PrefixList="wsu wsse S" />
    													</ds:Transform>
    												</ds:Transforms>
    												<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
    												<ds:DigestValue>qLyQw9dHKg57HBNbhP5StzRzrvg=</ds:DigestValue>
    											</ds:Reference>
    										</ds:SignedInfo>
    										<ds:SignatureValue>IxAq16stwyEDmwBfMSPyr6bK6iM=</ds:SignatureValue>
    										<ds:KeyInfo>
    											<wsse:SecurityTokenReference>
    												<wsse:KeyIdentifier
    													ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKeySHA1"
    													EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">1qs60T2OmXwSq32UjIGrMmasdm4=</wsse:KeyIdentifier>
    											</wsse:SecurityTokenReference>
    										</ds:KeyInfo>
    									</ds:Signature>
    								</wsse:Security>
    							</S:Header>
    							<S:Body>
    								<ns2:greetCustomerResponse xmlns:ns2="http://service.globinch.com/">
    									<return>
    										Hello...Friend
    									</return>
    								</ns2:greetCustomerResponse>
    							</S:Body>
    						</S:Envelope>
    						--uuid:bd210aea-ae7f-4bc2-8da8-800c509204ba----------------------
    
    

    References:

    Incoming search terms:

    8 Flares Twitter 0 Facebook 0 Google+ 7 LinkedIn 1 Email -- Filament.io 8 Flares ×

    About Binu George

    2 thoughts on “Secure Metro JAX-WS UsernameToken Web Service with Signature, Encryption and TLS (SSL)

    1. Giuseppe Capone says:

      Hello,
      Very very useful guide!!!
      I have a problem.
      In this article, it’s explained how to encrypt the username token but I would like to encrypt soap body also. Username token and soap body both encrypted & signed. Can you help me?

    2. faisal says:

      can you tell me how this can be configured to execute as a stand alone client?

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    Paged comment generated by AJAX Comment Page

    Google+ Plus Follow on Twitter Like On Facebook Linked Follow

    Popular post

    JAX-WS Web Services and Clients Java JAX-WS Tutorial: Develop Web Services and Clients (Consumers) Using JAX-WS
    jax-ws usernametoken example JAX-WS and Secure Java Web Services using UsernameToken : WS-Security with Metro and WSIT
    How to Fix : java.security.cert.CertificateException: No name matching localhost found
    JAX-WS exception fault handling example JAX-WS Exceptions and Faults: Annotation, Exception and Fault Handling Examples
    SOAP Binding: Difference between Document and RPC Style Web Services

    Subscribe to Enterprise Java newsletter
    Subscribe
    Get Enterprise Java Newsletter

    Enter your email and stay on top of things,