Using SOAP Headers to Enable WS-Security

WS-Security ensures the identify, integrity, and security of a SOAP message. It is applied at the Web service layer, as opposed to basic access authentication, which is applied at the HTTP transport layer. SOAP messages are typically exchanged over HTTP, so you can use basic access authentication for them. However, WS-Security provides an extra level of security for messages that take a complicated path or that use a non-HTTP transport mechanism.

WS-Security elements are embedded within the SOAP message <env:Header> element. These take the form of one or more <wss:security> elements that contain the appropriate security information as required by the particular service deployment.

Although it is possible to declare WS-Security elements in a Web service WSDL file, this is not typically done. Instead, WS-Policy is used to document the security that a particular service requires. SBM does not currently support WS-Policy. However, it is possible to use data mapping in SBM Composer to create SOAP header elements.

To do this, there must be at least one declared header in the Web service WSDL. Any header will do; It does not have to be a WS-Security header. Because headers are not typically present in Web service WSDLs, you probably need to make a local copy of the WSDL and then edit it to add a placeholder header.

CAUTION:
Do not import the WS-Security schema into your copy of the WSDL or into SBM Composer to get the WS-Security <env:Header> elements and types. The way the schema is declared is problematic, and there is inadequate support for it from SBM Composer.

To enable WS-Security:

  1. Create a Placeholder element and a Header message in the WSDL file as shown in bold and italics in the following example. The Placeholder element causes SBM Composer to provide an _Envelope element in the SOAP request message. The Header message will contain the WS-Security data, which mirrors the UsernameToken element in the WS-Security schema.
    Note: This example contains only one operation. If there are more operations you will need to declare a header for each one you want to use. You can typically reference the same header message declaration.
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:tns="http://www.example.org/SOAPHeaderExample_1/" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd=
    "http://www.w3.org/2001/XMLSchema" name="SOAPHeaderExample_1" 
    targetNamespace="http://www.example.org/SOAPHeaderExample_1/">
      <wsdl:types>
        <xsd:schema targetNamespace="http://www.example.org/
    SOAPHeaderExample_1/">
          <xsd:element name="NewOperation">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="in" type="xsd:string"/>
              </xsd:sequence>
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="NewOperationResponse">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="out" type="xsd:string"/>
              </xsd:sequence>
            </xsd:complexType>
          </xsd:element>
         <xsd:element name="Placeholder" type="xsd:string"/>
        </xsd:schema>
      </wsdl:types>
      <wsdl:message name="NewOperationRequest">
        <wsdl:part element="tns:NewOperation" name="parameters"/>
      </wsdl:message>
      <wsdl:message name="NewOperationResponse">
        <wsdl:part element="tns:NewOperationResponse" name="parameters"/>
      </wsdl:message>
      <wsdl:message name="Header">
        <wsdl:part element="tns:Placeholder" name="placeholder"/>
      </wsdl:message>
      <wsdl:portType name="SOAPHeaderExample_1">
        <wsdl:operation name="NewOperation">
          <wsdl:input message="tns:NewOperationRequest"/>
          <wsdl:output message="tns:NewOperationResponse"/>
        </wsdl:operation>
      </wsdl:portType>
      <wsdl:binding name="SOAPHeaderExample_1SOAP" type="tns:
    SOAPHeaderExample_1">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/
    soap/http"/>
        <wsdl:operation name="NewOperation">
          <soap:operation soapAction="http://www.example.org/
    SOAPHeaderExample_1/NewOperation"/>
        <wsdl:input>
          <soap:body use="literal"/>
          <soap:header message="tns:Header" part="placeholder" 
    use="literal" />
        </wsdl:input>
        <wsdl:output>
          <soap:body use="literal"/>
        </wsdl:output>
      </wsdl:operation>
      </wsdl:binding>
      <wsdl:service name="SOAPHeaderExample_1">
        <wsdl:port binding="tns:SOAPHeaderExample_1SOAP" name=
    "SOAPHeaderExample_1SOAP">
          <soap:address location="http://www.example.org/"/>
        </wsdl:port>
      </wsdl:service>
    </wsdl:definitions>
    
    Tip: In the example above, note that the Placeholder namespace matches the namespace that is used for http://www.w3.org/2001/XMLSchema (xsd). If the namespace was <wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema", you would insert <s:element name="Placeholder" type="s:string"/> to match the namespace.
  2. Import the WSDL file into SBM Composer:
    1. Select the Web Services header under the orchestration in App Explorer.
    2. Right-click and then select Add New Web Service.
    3. In the Web Service Configuration dialog box that opens, browse to the WSDL file and then click OK.
  3. Click the Data Mapping tab in the orchestration workflow editor, and add working data elements as shown below to store the WS-Security data. Use the exact names and types, because they mirror the structure of the particular WS-Structure you need to use. Declare each element with the following namespace: http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wsssecurity-secext-1.0.xsd.

    image

    Note: SBM Composer has some limitations as to the structures it can create. You can usually work around these limitations by declaring the structure you need in the WSDL schema. Due to problems with the WS-Security schema, you cannot use it directly and will need to recreate the appropriate WS-Security structure in the Web service WSDL.
    In this example used in this topic, the WS-Security UsernameToken structure is used:
    <wsse:Security>
        <wsse:UsernameToken>
            <wsse:Username>theUsername</wsse:Username>
            <wsse:Password>thePassword</wsse:Password>
        </wsse:UsernameToken>
    </wsse:Security>
    
  4. Type a default value for the Username and Password, or click in the Source elements column and then map to values. If you do not do this, the values will not appear in the SOAP message.

    image

  5. In the orchestration workflow editor, select the Service step.
  6. On the Data Mapping tab of the step Property Editor, map the _Envelope step input to the SOAPHeader working data element that will store the security data.

    image

    The following example SOAP request shows the result of this procedure.
    <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/
    envelope/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <env:Header>
          <ns9:Security xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/
    business-process/" xmlns:defaultNS="http://SOAPHeaderTest1" 
    xmlns:defaultNS1="http://www.example.org/SOAPHeaderExample_1/" 
    xmlns:ns9="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-
    wssecurity-secext-1.0.xsd" xmlns:tns="http://SOAPHeaderTest1">
             <ns9:Username>theUsername</ns9:Username>
             <ns9:Password>thePassword</ns9:Password>
          </ns9:Security>
       </env:Header>
       <env:Body>
          <defaultNS1:NewOperation 
    xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/" 
    xmlns:defaultNS="http://www.example.org/SOAPHeaderExample_1/" 
    xmlns:defaultNS1="http://www.example.org/SOAPHeaderExample_1/" 
    xmlns:ns8="http://www.example.org/SOAPHeaderExample_1/">
             <in xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:ns1="http://www.eclipse.org/alf/schema/EventBase/1" 
    xmlns:s="http://www.eclipse.org/alf/schema/EventBase/1" 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">hello</in>
          </defaultNS1:NewOperation>
       </env:Body>
    </env:Envelope>

Related Topics

Using Data Mapping

About SOAP Messages

Mapping SOAP Header Data