Custom SOAP Headers

Credential checking is enforced in IBM Cúram Social Program Management for web service invocations based on the default expectation that a client invoking a web service will provide a custom SOAP header. This topic was introduced in Providing Web Service Customizations insofar as you need to plan specific customizations if you choose to bypass this security checking. By default, the provided receivers for Axis2 expect the client invocation of each web service to provide a custom SOAP header that contains credentials for authenticating IBM Cúram Social Program Management access to the web service. This section explains how your clients can provide these SOAP headers.

The following is an example of the IBM Cúram Social Program Management custom SOAP header in the context of the SOAP message:

Figure 1. Example Custom SOAP Header
<?xml version='1.0' encoding='UTF-8'?>
       <soapenv:Envelope
         xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
          <soapenv:Header>
             <curam:Credentials
               xmlns:curam="http://www.curamsoftware.com">
                <Username>testerID</Username>
                <Password>password</Password>
             </curam:Credentials>
          </soapenv:Header>
          <soapenv:Body>
            <!-- SOAP message body data here. -->
          </soapenv:Body>
       </soapenv:Envelope>

The following is a sample client method for creating custom SOAP headers:

Figure 2. Sample Method to Create Custom SOAP Headers
import org.apache.axis2.client.ServiceClient;
import javax.xml.namespace.QName;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPHeaderBlock;

...

/**
 * Create custom SOAP header for web service credentials.
 *
 * @param serviceClient Web service client
 * @param userName      User name
 * @param password      Password
*/
void setCuramCredentials(final ServiceClient serviceClient,
  final String userName, final String password)

    // Setup and create the header
    final SOAPFactory factory =
      OMAbstractFactory.getSOAP12Factory();
    final OMNamespace ns =
      factory.createOMNamespace("http://www.curamsoftware.com",
      "curam");
    final SOAPHeaderBlock header =
      factory.createSOAPHeaderBlock("Credentials", ns);
    final OMFactory omFactory = OMAbstractFactory.getOMFactory();

    // Set the username.
    final OMNode userNameNode =
      omFactory.createOMElement(new QName("Username"));
    ((OMElement) userNameNode).setText(userName);
    header.addChild(userNameNode);

    // Set the password.
    final OMNode passwordNode =
      omFactory.createOMElement(new QName("Password"));
    ((OMElement) passwordNode).setText(password);
    header.addChild(passwordNode);

    serviceClient.addHeader(header);
}

Then a call to the above method would appear as:

// Set the credentials for the web service:
    MyWebServiceStub stub =
      new MyWebServiceStub();
    setCuramCredentials(stub._getServiceClient(),
      "system", "password");

By default, the client failing to provide this custom header will cause the service to not be invoked. And, of course, incorrect or invalid credentials will cause an authentication error. The following is an example of failing to provide the necessary custom SOAP header:

<soapenv:Envelope xmlns:
  soapenv="http://www.w3.org/2003/05/soap-envelope">
  <soapenv:Body>
    <soapenv:Fault>
      <soapenv:Code>
        <soapenv:Value
          >soapenv:Receiver</soapenv:Value>
      </soapenv:Code>
      <soapenv:Reason>
        <soapenv:Text xml:lang="en-US">
          No authentication data.
        </soapenv:Text>
      </soapenv:Reason>
        <soapenv:Detail/>
    </soapenv:Fault>
  </soapenv:Body>
</soapenv:Envelope>
warning: Potential Security Vulnerability

Be aware that by default custom SOAP headers containing credentials for authentication pass on the wire in plain-text! This is an unsecure situation and you must encrypt this traffic to prevent your credentials from being vulnerable and your security from being breached. See Encrypting Custom SOAP Headers and/or Securing Web Service Network Traffic With HTTPS/SSL on how you might rectify this.

For example, this is what the custom SOAP header looks like in the SOAP message with the credentials visible:

Figure 3. Sample Custom SOAP Header
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope
  xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
  <soapenv:Header>
    <curam:Credentials
      xmlns:curam="http://www.curamsoftware.com">
      <Username>tester</Username>
      <Password>password</Password>
    </curam:Credentials>
  </soapenv:Header>
  <soapenv:Body>
    ...
  </soapenv:Body>
</soapenv:Envelope>