Secure a web service using a WS-Security policy

We can develop and secure a Java API for XML Web Services (JAX-WS) web service using a WS-Security policy in WebSphere Application Server Liberty. The examples are provided as a tutorial to explain the general steps involved in developing and securing a web service in Liberty.

Show how to develop a simple JAX-WS web service application and secure that application using a WS-Security policy. Do not use these examples in a production environment. Review our own security requirements to develop the Web Services Description Language (WSDL) contract and the WS-Security policy for protecting your web service applications.

These examples use two sample keystore files, enc-sender.jceks and enc-receiver.jceks, which we can either obtain from a WebSphere Application Server traditional instance or generate using the Java keytool command.

These keystore files are WS-Security sample keystores that are included in WebSphere Application Server traditional. If we have access to a traditional installation, we can obtain the sample keystores from one the following directories.

profile_root/etc/ws-security/samples

WASHOME/profileTemplates/defaultdocuments/etc/ws-security/samples If we do not have access to a WebSphere Application Server traditional instance, we can generate the sample keystore files using the following Java keytool commands. The examples that use these files reference two sample users, Alice and Bob. We must first create the enc-sender.jceks keystore, which contains a self-signed certificate for Alice, and the enc-receiver.jceks keystore, which contains a self-signed certificate for Bob. We must then extract Alice's key and import it to Bob's keystore and extract Bob's key and import it to Alice's keystore.

  • To create the enc-sender.jceks keystore, which contains the self-signed certificate for Alice, run the following command.

      keytool -genkeypair -alias alice -dname "CN=Alice, O=IBM, C=US" -storetype jceks -validity 2000 -keystore enc-sender.jceks -storepass storepswd -keypass keypswd

  • To create the enc-receiver.jceks keystore, which contains the self-signed certificate for Bob, run the following command.

      keytool -genkeypair -alias bob -dname "CN=Bob, O=IBM, C=US" -storetype jceks -validity 2000 -keystore enc-receiver.jceks -storepass storepswd -keypass keypswd

  • To extract Alice's key and import to Bob's enc-receiver.jceks keystore, run the following commands.

      keytool -export -keystore enc-sender.jceks -alias alice -file alice.cert -storetype jceks -storepass storepswd
      keytool -import -keystore enc-receiver.jceks -storetype jceks -file alice.cert -storepass storepswd -alias alice

  • To extract Bob's key and import to Alice's enc-sender.jceks keystore, run the following commands.

      keytool -export -keystore enc-receiver.jceks -alias bob -file bob.cert -storetype jceks -storepass storepswd
      keytool -import -keystore enc-sender.jceks -storetype jceks -file bob.cert -storepass storepswd -alias bob

After you obtain or generate the keystore files, ensure they are in your ${server.config.dir} directory and proceed with the following examples.

  1. Create the WSDL contract and WS-Security policy. In this sample, a WSDL contract with a WS-Security policy for a JAX-WS web service provider application is created. The WS-Security policy template called UsernameToken with X509Token asymmetric message protection (mutual authentication) is used. The client signs and encrypts the SOAP body and signs and encrypts the UsernameToken in the request message. In the response message, the provider signs and encrypts the SOAP body. For a complete description of the security constraints in this example, see UsernameToken with X509Token asymmetric message protection (mutual authentication).

    1. Create a WSDL contract for your service. The following example shows a sample WSDL contract.

        <?xml version="1.0" encoding="UTF-8"?>
        <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
          xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
          xmlns:tns="http://com/ibm/was/wssample/sei/echo/"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="WSSampleSei"
          targetNamespace="http://com/ibm/was/wssample/sei/echo/">
          <wsdl:types>
            <xsd:schema targetNamespace="http://com/ibm/was/wssample/sei/echo/"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema">
              <xsd:element name="echoStringResponse">
                <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="echoResponse" type="xsd:string" />
          </xsd:sequence>
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="echoStringInput">
                <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="echoInput" type="xsd:string" />
          </xsd:sequence>
                </xsd:complexType>
              </xsd:element>
            </xsd:schema>
          </wsdl:types>
          <wsdl:message name="echoOperationRequest">
            <wsdl:part element="tns:echoStringInput" name="parameter" />
          </wsdl:message>
          <wsdl:message name="echoOperationResponse">
            <wsdl:part element="tns:echoStringResponse" name="parameter" />
          </wsdl:message>
          <wsdl:portType name="EchoServicePortType">
            <wsdl:operation name="echoOperation">
              <wsdl:input message="tns:echoOperationRequest" />
              <wsdl:output message="tns:echoOperationResponse" />
            </wsdl:operation>
          </wsdl:portType>
          <wsdl:binding name="Echo1SOAP" type="tns:EchoServicePortType">
            <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
            <wsdl:operation name="echoOperation">
              <soap:operation soapAction="echoOperation" style="document" />
              <wsdl:input>
                <soap:body use="literal" />
              </wsdl:input>
              <wsdl:output>
                <soap:body use="literal" />
              </wsdl:output>
            </wsdl:operation>
          </wsdl:binding>
          <wsdl:service name="Echo1Service">
            <wsdl:port binding="tns:Echo1SOAP" name="Echo1ServicePort">
              <soap:address location="http://localhost:8010/WSSampleSei/Echo1Service" />
            </wsdl:port>
          </wsdl:service>
        </wsdl:definitions>

    2. Add the namespaces needed to support the security policy to your WSDL in the wsdl:definitions element. The following example shows the added namespaces.

        xmlns:wsp="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:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
        xmlns:sp13="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802"
        xmlns:wsaws="http://www.w3.org/2005/08/addressing"

    3. Add the WS-Security policy fragment to your WSDL just before the wsdl:binding element. The policy template from UsernameToken with X509Token asymmetric message protection (mutual authentication) is used in this example.

    4. Add a wsp:PolicyReference for your security policy to your wsdl:binding element. The following example shows the wsp:PolicyReference.

        <wsp:PolicyReference URI="#AsymmetricX509MutualAuthenticationWithUnt" />

    5. Verify that your final WSDL looks like the example. The following example shows the final WSDL.

        <?xml version="1.0" encoding="UTF-8"?>
        <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
          xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
          xmlns:tns="http://com/ibm/was/wssample/sei/echo/"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="WSSampleSei"
          xmlns:wsp="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:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
          xmlns:sp13="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802"
          xmlns:wsaws="http://www.w3.org/2005/08/addressing"
          targetNamespace="http://com/ibm/was/wssample/sei/echo/">
          <wsdl:types>
            <xsd:schema targetNamespace="http://com/ibm/was/wssample/sei/echo/"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema">
              <xsd:element name="echoStringResponse">
                <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="echoResponse" type="xsd:string" />
          </xsd:sequence>
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="echoStringInput">
                <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="echoInput" type="xsd:string" />
          </xsd:sequence>
                </xsd:complexType>
              </xsd:element>
            </xsd:schema>
          </wsdl:types>
          <wsdl:message name="echoOperationRequest">
            <wsdl:part element="tns:echoStringInput" name="parameter" />
          </wsdl:message>
          <wsdl:message name="echoOperationResponse">
            <wsdl:part element="tns:echoStringResponse" name="parameter" />
          </wsdl:message>
          <wsdl:portType name="EchoServicePortType">
            <wsdl:operation name="echoOperation">
              <wsdl:input message="tns:echoOperationRequest" />
              <wsdl:output message="tns:echoOperationResponse" />
            </wsdl:operation>
          </wsdl:portType>
          <wsp:Policy wsu:Id="AsymmetricX509MutualAuthenticationWithUnt">
            <wsp:ExactlyOne>
              <wsp:All>
                <sp:SignedEncryptedSupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <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:AsymmetricBinding>
          <wsp:Policy>
            <sp:InitiatorToken>
              <wsp:Policy>
                <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
          <wsp:Policy>
         <sp:WssX509V3Token10 />
         <sp:RequireIssuerSerialReference />
          </wsp:Policy>
                </sp:X509Token>
              </wsp:Policy>
            </sp:InitiatorToken>
            <sp:RecipientToken>
              <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:RecipientToken>
            <sp:Layout>
              <wsp:Policy>
                <sp:Strict />
              </wsp:Policy>
            </sp:Layout>
            <sp:IncludeTimestamp />
            <sp:OnlySignEntireHeadersAndBody />
            <sp:EncryptSignature />
            <sp:AlgorithmSuite>
              <wsp:Policy>
                <sp:Basic128 />
              </wsp:Policy>
            </sp:AlgorithmSuite>
          </wsp:Policy>
                </sp:AsymmetricBinding>
                <sp:Wss11>
          <wsp:Policy>
            <sp:MustSupportRefKeyIdentifier />
            <sp:MustSupportRefIssuerSerial />
            <sp:MustSupportRefThumbprint />
            <sp:MustSupportRefEncryptedKey />
            <sp:RequireSignatureConfirmation />
          </wsp:Policy>
                </sp:Wss11>
                <sp:SignedParts>
          <sp:Body />
                </sp:SignedParts>
                <sp:EncryptedParts>
          <sp:Body />
                </sp:EncryptedParts>
              </wsp:All>
            </wsp:ExactlyOne>
          </wsp:Policy>
          <wsdl:binding name="Echo1SOAP" type="tns:EchoServicePortType">
            <wsp:PolicyReference URI="#AsymmetricX509MutualAuthenticationWithUnt" />
            <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
            <wsdl:operation name="echoOperation">
              <soap:operation soapAction="echoOperation" style="document" />
              <wsdl:input>
                <soap:body use="literal" />
              </wsdl:input>
              <wsdl:output>
                <soap:body use="literal" />
              </wsdl:output>
            </wsdl:operation>
          </wsdl:binding>
          <wsdl:service name="Echo1Service">
            <wsdl:port binding="tns:Echo1SOAP" name="Echo1ServicePort">
              <soap:address location="http://localhost:8010/WSSampleSei/Echo1Service" />
            </wsdl:port>
          </wsdl:service>
        </wsdl:definitions>

  2. Create the web service application using WSDL. This step can be done before or after the WS-Security policy is added to the WSDL. We can use supported tools to create a JAX-WS web service application from the WSDL that was developed in the previous section. The following example shows a web service application that is developed from the WSDL using the Rational Application Developer tool.

      @javax.jws.WebService (endpointInterface="com.ibm.was.wssample.sei.echo.EchoServicePortType",
          targetNamespace="http://com/ibm/was/wssample/sei/echo/", 
          serviceName="Echo1Service", 
          wsdlLocation = "WEB-INF/wsdl/Echo.wsdl",
          portName="Echo1ServicePort")
      public class Echo1SOAPImpl { 
        public EchoStringResponse echoOperation(EchoStringInput parameter) {     String strInput = (parameter == null ? "input_is_null" : parameter.getEchoInput() );
          try {       com.ibm.was.wssample.sei.echo.EchoStringResponse strOutput = new EchoStringResponse();
            strOutput.setEchoResponse( "Echo1SOAPImpl>>" + strInput );
            return strOutput;
          } catch (java.lang.Exception ex) {       ex.printStackTrace();
          }
        }
      
      @WebService (name = "EchoServicePortType", 
           targetNamespace = "http://com/ibm/was/wssample/sei/echo/")
      @SOAPBinding (parameterStyle = SOAPBinding.ParameterStyle.BARE)
      @Xml

      SeeAlso ({ ObjectFactory.class }) public interface EchoServicePortType { @WebMethod (action = "echoOperation") @WebResult (name = "echoStringResponse", targetNamespace = "http://com/ibm/was/wssample/sei/echo/", partName = "parameter") public EchoStringResponse echoOperation( @WebParam (name = "echoStringInput", targetNamespace = "http://com/ibm/was/wssample/sei/echo/", partName = "parameter") EchoStringInput parameter); }

    The following code shows a managed web service client that invokes a web service provider application.

      @WebServlet("ClientServlet")
      public class ClientServlet extends HttpServlet { 
        @WebServiceRef (value=Echo1Service.class, wsdlLocation="Echo.wsdl")
        Echo1Service echo1Service;
      
        public  ClientServlet() {     super ();
        }
      
        protected void doGet(HttpServletRequest request,
          HttpServletResponse response) throws ServletException, IOException {     processRequest(request, response);
        } 
      
        protected void doPost(HttpServletRequest request,
           HttpServletResponse response) throws ServletException, IOException {     processRequest(request, response);
        }
      
        private void processRequest(HttpServletRequest req,
         HttpServletResponse resp) throws ServletException, IOException { 
          String endpointURL = "http://localhost:8010/WSSampleSei/Echo1Service";
      
          Echo1ServicePortProxy proxy = new Echo1ServicePortProxy(echo1Service);
          proxy._getDescriptor().setEndpoint(endpointURL);
      
          echoParm = new ObjectFactory().createEchoStringInput();
          echoParm.setEchoInput("Hello");
      
          String retval = proxy.echoOperation(echoParm).getEchoResponse();
      
        }
      }

    The following example shows the file structure of the web service provider application war file.

      WEB-INF/web.xml
      WEB-INF/wsdl/Echo.wsdl
      WEB-INF/classes/com/ibm/was/wssample/sei/echo/Echo1SOAPImpl.class
      WEB-INF/classes/com/ibm/was/wssample/sei/echo/EchoServicePortType.class
      WEB-INF/classes/com/ibm/was/wssample/sei/echo/EchoStringInput.class
      WEB-INF/classes/com/ibm/was/wssample/sei/echo/EchoStringResponse.class
      WEB-INF/classes/com/ibm/was/wssample/sei/echo/ObjectFactory.class
      WEB-INF/classes/com/ibm/was/wssample/sei/echo/package-info.class

    The following example shows the file structure of the web service client application war file.

      WEB-INF/web.xml
      WEB-INF/wsdl/Echo.wsdl
      WEB-INF/classes/com/ibm/was/wssample/client/ClientServlet.class
      WEB-INF/classes/com/ibm/was/wssample/client/SampleClient.class
      WEB-INF/classes/com/ibm/was/wssample/sei/echo/Echo1Service.class
      WEB-INF/classes/com/ibm/was/wssample/sei/echo/Echo1ServicePortProxy.class
      WEB-INF/classes/com/ibm/was/wssample/sei/echo/EchoStringInput.class
      WEB-INF/classes/com/ibm/was/wssample/sei/echo/EchoStringResponse.class
      WEB-INF/classes/com/ibm/was/wssample/sei/echo/ObjectFactory.class
      WEB-INF/classes/com/ibm/was/wssample/sei/echo/package-info.class     

  3. Develop the callback handler. We must develop a callback handler to retrieve the username and keystore key passwords. The username password is used when you generate the UsernameTokens. The keystore passwords are used for accessing the private keys in the keystore. The callback handler must return plain text passwords and be packaged and installed as a Liberty user feature.The following sample code illustrates a callback handler.

      package com.ibm.ws.wssecurity.example.cbh;
      
      import java.util.HashMap;
      import java.util.Map;
      import javax.security.auth.callback.Callback;
      import javax.security.auth.callback.CallbackHandler;
      import org.apache.ws.security.WSPasswordCallback;
      
      public class SamplePasswordCallback implements CallbackHandler {   private Map<String, String> userPasswords = new HashMap<String, String>();
        private Map<String, String> keyPasswords = new HashMap<String, String>();
        public SamplePasswordCallback() {     // some example user passwords
          userPasswords.put("user1", "user1pswd");
          userPasswords.put("admin", "adminpswd");
          // some example key passwords
          keyPasswords.put("alice", "keypwsd");
          keyPasswords.put("bob", "keypswd");
        }
        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {     for (int i = 0; i < callbacks.length; i++) {       WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
            String id = pwcb.getIdentifier();
            String pass = null;
            switch (pwcb.getUsage()) { case WSPasswordCallback.USERNAME_TOKEN:
        pass = userPasswords.get(id);
        pwcb.setPassword(pass);
        break;
              case WSPasswordCallback.SIGNATURE:
              case WSPasswordCallback.DECRYPT:
        pass = keyPasswords.get(id);
        pwcb.setPassword(pass);
        break;
            }
          }
        }
      }

    The following example shows the MANIFEST.MF file that is packaged with the callback handler.

      Manifest-Version: 1.0
      Bnd-LastModified: 1359415594428
      Build-Identifier: SNAPSHOT-Mon Jan 28 17:26:34 CST 2013
      Bundle-Description: An PasswordCallbackHandler; version=1.0.0
      Bundle-ManifestVersion: 2
      Bundle-Name: wssecuritycbh
      Bundle-SymbolicName: com.ibm.ws.wssecurity.example.cbh
      Bundle-Vendor: IBM
      Bundle-Version: 1.0.0
      Created-By: 1.6.0 (IBM Corporation)
      Export-Package: com.ibm.ws.wssecurity.example.cbh;uses:="com.ibm.websphe
      re.ras.annotation,javax.security.auth.callback";version="1.0.0"
      Import-Package: com.ibm.websphere.ras,com.ibm.websphere.ras.annotation,c
      om.ibm.ws.ffdc,javax.security.auth.callback,org.apache.ws.security;version="[1.6,2)"
      Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=1.6))"
      Tool: Bnd-2.1.0.20120920-170235
      WS-TraceGroup: WSSecurity

    1. Create a JAR file with the callback handler and the feature manifest file - wsseccbh-1.0.mf. Create a JAR file called SampleCbh.jar with the following contents.

        META-INF/MANIFEST.MF
        com/ibm/ws/wssecurity/example/cbh/SamplePasswordCallback.class

      The following example shows the wsseccbh-1.0.mf file.

        Subsystem-ManifestVersion: 1
        Subsystem-SymbolicName: wsseccbh-1.0; visibility:=public
        Subsystem-Version: 1.0.0
        Subsystem-Content: com.ibm.ws.wssecurity.example.cbh; version="[1,1.0.100)";
            location:="lib/"; type="osgi.bundle"; start-phase:=APPLICATION_EARLY
        
        Subsystem-Type: osgi.subsystem.feature
        IBM-Feature-Version: 2
        
        IBM-API-Package: com.ibm.ws.wssecurity.example.cbh; version="1.0"; type="internal"

    2. Copy the callback handler JAR file and the feature manifest file under the Liberty user directory. The following example shows where the callback handler JAR file and the feature manifest file are copied.

        build.image/wlp/usr/extension/lib/SampleCbh.jar
        build.image/wlp/usr/extension/lib/features/wsseccbh-1.0.mf

  4. Configure WS-Security in the Liberty server. Enable the WS-Security feature in the Liberty server configuration file: server.xml and configure WS-Security for the sample web service client and provider application that is developed in the previous sections.The following example shows how to configure WS-Security.

      <server>
        <featureManager>
          <feature>usr:wsseccbh-1.0</feature>
          <feature>servlet-3.0</feature>
          <feature>appSecurity-2.0</feature>
          <feature>jsp-2.2</feature>
          <feature>jaxws-2.2</feature>
          <feature>wsSecurity-1.1</feature>
        </featureManager>
        <basicRegistry id="basic" realm="customRealm">
          <user ="user1" password="user1pswd" />
          <user name="user2" password="user2pswd" />
        </basicRegistry>
        <wsSecurityProvider id="default"
          ws-security.callback-handler="com.ibm.ws.wssecurity.example.cbh.SamplePasswordCallback"
          ws-security.signature.username="bob">
          <signatureProperties org.apache.ws.security.crypto.merlin.keystore.type="jceks"
            org.apache.ws.security.crypto.merlin.keystore.password="storepswd"
            org.apache.ws.security.crypto.merlin.keystore.alias="bob"
            org.apache.ws.security.crypto.merlin.file="${server.config.dir}/enc-receiver.jceks" />
          <encryptionProperties org.apache.ws.security.crypto.merlin.keystore.type="jceks"
            org.apache.ws.security.crypto.merlin.keystore.password="storepswd"
            org.apache.ws.security.crypto.merlin.keystore.alias="alice"
            org.apache.ws.security.crypto.merlin.file="${server.config.dir}/enc-receiver.jceks" />
        </wsSecurityProvider>
        <wsSecurityClient id="default"
          ws-security.password="security"
          ws-security.username="user1"
          ws-security.callback-handler="com.ibm.ws.wssecurity.example.cbh.SamplePasswordCallback"
          ws-security.encryption.username="alice">
          <signatureProperties org.apache.ws.security.crypto.merlin.keystore.type="jceks"
            org.apache.ws.security.crypto.merlin.keystore.password="storepswd"
            org.apache.ws.security.crypto.merlin.keystore.alias="alice"
            org.apache.ws.security.crypto.merlin.file="${server.config.dir}/enc-sender.jceks"/>
          <encryptionProperties org.apache.ws.security.crypto.merlin.keystore.type="jceks"
            org.apache.ws.security.crypto.merlin.keystore.password="storepswd"
            org.apache.ws.security.crypto.merlin.keystore.alias="bob"
            org.apache.ws.security.crypto.merlin.file="${server.config.dir}/enc-sender.jceks" />
        </wsSecurityClient>
      </server>

You secured a web service using a WS-Security policy.


Example

The sample WS-Security policy that was created in the first step generates SOAP request and response messages that are similar to the following messages.The following example shows the SOAP request message.

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
        <wsse:Security 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"
       soap:mustUnderstand="1">
          <wsse:BinarySecurityToken
            EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
            ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
            wsu:Id="X509-B1165B2A578AFFC7D613649595665924">...
          </wsse:BinarySecurityToken>
          <wsu:Timestamp wsu:Id="TS-1">
            <wsu:Created>2013-04-03T03:26:06.549Z</wsu:Created>
            <wsu:Expires>2013-04-03T03:31:06.549Z</wsu:Expires>
          </wsu:Timestamp>
          <xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="EK-B1165B2A578AFFC7D613649595666705">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"></xenc:EncryptionMethod>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <wsse:SecurityTokenReference>
        <ds:X509Data>
          <ds:X509IssuerSerial>
            <ds:X509IssuerName>CN=Bob,O=IBM,C=US</ds:X509IssuerName>
            <ds:X509SerialNumber>24054675667389</ds:X509SerialNumber>
          </ds:X509IssuerSerial>
        </ds:X509Data>
      </wsse:SecurityTokenReference>
            </ds:KeyInfo>
            <xenc:CipherData>
      <xenc:CipherValue>...</xenc:CipherValue>
            </xenc:CipherData>
            <xenc:ReferenceList>
      <xenc:DataReference URI="#ED-4"></xenc:DataReference>
      <xenc:DataReference URI="#ED-5"></xenc:DataReference>
      <xenc:DataReference URI="#ED-6"></xenc:DataReference>
            </xenc:ReferenceList>
          </xenc:EncryptedKey>
          <xenc:EncryptedData
            xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED-6" Type="http://www.w3.org/2001/04/xmlenc#Element">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"></xenc:EncryptionMethod>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <wsse:SecurityTokenReference
        xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
        xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
        wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
        <wsse:Reference URI="#EK-B1165B2A578AFFC7D613649595666705"></wsse:Reference>
      </wsse:SecurityTokenReference>
            </ds:KeyInfo>
            <xenc:CipherData>
      <xenc:CipherValue>...</xenc:CipherValue>
            </xenc:CipherData>
          </xenc:EncryptedData>
          <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
           Id="ED-5"
           Type="http://www.w3.org/2001/04/xmlenc#Element">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"></xenc:EncryptionMethod>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <wsse:SecurityTokenReference
        xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
        xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
        wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
        <wsse:Reference URI="#EK-B1165B2A578AFFC7D613649595666705"></wsse:Reference>
      </wsse:SecurityTokenReference>
            </ds:KeyInfo>
            <xenc:CipherData>
      <xenc:CipherValue>...</xenc:CipherValue>
            </xenc:CipherData>
          </xenc:EncryptedData>
        </wsse:Security>
      </SOAP-ENV:Header>
      <soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
         wsu:Id="Id-1788936596">
        <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
         Id="ED-4"
         Type="http://www.w3.org/2001/04/xmlenc#Content">
          <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"></xenc:EncryptionMethod>
          <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <wsse:SecurityTokenReference
      xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
      xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
      wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
      <wsse:Reference URI="#EK-B1165B2A578AFFC7D613649595666705"></wsse:Reference>
            </wsse:SecurityTokenReference>
          </ds:KeyInfo>
          <xenc:CipherData>
            <xenc:CipherValue>...</xenc:CipherValue>
          </xenc:CipherData>
        </xenc:EncryptedData>
      </soap:Body>
    </soap:Envelope>

The following example shows a SOAP response message.

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
        <wsse:Security 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"
       soap:mustUnderstand="1">
          <wsu:Timestamp wsu:Id="TS-7">
            <wsu:Created>2013-04-03T03:26:07.286Z</wsu:Created>
            <wsu:Expires>2013-04-03T03:31:07.286Z</wsu:Expires>
          </wsu:Timestamp>
          <xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="EK-B1165B2A578AFFC7D613649595673129">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"></xenc:EncryptionMethod>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <wsse:SecurityTokenReference>
        <ds:X509Data>
          <ds:X509IssuerSerial>
            <ds:X509IssuerName>CN=Alice,O=IBM,C=US</ds:X509IssuerName>
            <ds:X509SerialNumber>24054530212598</ds:X509SerialNumber>
          </ds:X509IssuerSerial>
        </ds:X509Data>
      </wsse:SecurityTokenReference>
            </ds:KeyInfo>
            <xenc:CipherData>
      <xenc:CipherValue>...</xenc:CipherValue>
            </xenc:CipherData>
            <xenc:ReferenceList>
      <xenc:DataReference URI="#ED-10"></xenc:DataReference>
      <xenc:DataReference URI="#ED-11"></xenc:DataReference>
      <xenc:DataReference URI="#ED-12"></xenc:DataReference>
            </xenc:ReferenceList>
          </xenc:EncryptedKey>
          <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
           Id="ED-12"
           Type="http://www.w3.org/2001/04/xmlenc#Element">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"></xenc:EncryptionMethod>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <wsse:SecurityTokenReference
        xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
        xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
        wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
        <wsse:Reference URI="#EK-B1165B2A578AFFC7D613649595673129"></wsse:Reference>
      </wsse:SecurityTokenReference>
            </ds:KeyInfo>
            <xenc:CipherData>
      <xenc:CipherValue>...</xenc:CipherValue>
            </xenc:CipherData>
          </xenc:EncryptedData>
          <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
           Id="ED-11"
           Type="http://www.w3.org/2001/04/xmlenc#Element">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"></xenc:EncryptionMethod>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <wsse:SecurityTokenReference
        xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
        xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
        wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
        <wsse:Reference URI="#EK-B1165B2A578AFFC7D613649595673129"></wsse:Reference>
      </wsse:SecurityTokenReference>
            </ds:KeyInfo>
            <xenc:CipherData>
      <xenc:CipherValue>...</xenc:CipherValue>
            </xenc:CipherData>
          </xenc:EncryptedData>
        </wsse:Security>
      </SOAP-ENV:Header>
      <soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
         wsu:Id="Id-2035943749">
        <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
         Id="ED-10"
         Type="http://www.w3.org/2001/04/xmlenc#Content">
          <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"></xenc:EncryptionMethod>
          <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <wsse:SecurityTokenReference
      xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
      xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
      wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
      <wsse:Reference URI="#EK-B1165B2A578AFFC7D613649595673129"></wsse:Reference>
            </wsse:SecurityTokenReference>
          </ds:KeyInfo>
          <xenc:CipherData>
            <xenc:CipherValue>...</xenc:CipherValue>
          </xenc:CipherData>
        </xenc:EncryptedData>
      </soap:Body>
    </soap:Envelope>


What to do next

We can now develop our own WSDL file and protect the web service application using a WS-Security policy that matches your security requirements.