Creating the WS-Security Header

Process Engine Web Service uses WS-Security to pass authentication information, carried as plaintext in a SOAP header. Currently, only the UsernameToken is supported. This needs to be present in every SOAP request, and needs to be set for your toolkit before generating source from the WSDL. The Username and Password values from the UsernameToken are authenticated using the (supported) enterprise directory service.

Use SOAP over HTTPS (SSL) to secure the authentication data. Refer to the topic Set Up Content Engine and Client Transport SSL Security in the IBM FileNet P8 Platform Installation and Upgrade Guide for instructions. (To download this document from the IBM support page, see Accessing IBM FileNet Documentation.)

The Process Engine Web Service SOAP header uses the following format:

<wsse:Security soap:mustUnderstand="1">
    <wsse:UsernameToken xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" 
        wsu:Id="SecurityToken-0c708387-2e7d-45b5-9029-b1108cf5527e">
        <wsse:Username>Administrator</wsse:Username> 
        <wsse:Password Type="wsse:PasswordText">secured</wsse:Password> 
    </wsse:UsernameToken>
</wsse:Security>

For more information about WS-Security, see Web Services Security.

Examples

The WS-Security header information is created differently depending on the web services toolkit you are using. Examples below are for Systinet and .NET.

.NET

WSE (Web Service Enhancements) 2.0 generates the WS-Security header information for you. Use coding similar to the following to have WSE generate this:

ProcessEngineServiceWse ws = new ProcessEngineServiceWse();
UsernameToken tok = new UsernameToken("Administrator""trident"
                                      PasswordOption.SendPlainText);
ws.RequestSoapContext.Security.Tokens.Add (tok);

Systinet

For Systinet, you need to create a server handler class and call it to generate the WS-Security header information. Use coding similar to the following:

import org.systinet.wasp.handler.WaspGenericHandler;
import org.systinet.wasp.webservice.CallContext;
import org.systinet.wasp.webservice.Current;

import javax.xml.namespace.QName;
import javax.xml.rpc.JAXRPCException;
import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.rpc.soap.SOAPFaultException;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import java.util.Map;
import filenet.vw.ws.server.Const;

public class ClientHandler extends WaspGenericHandler {
    public static final String USER_NAME_KEY = "username";
    public static final String PASSWORD_KEY  = "password";

    public boolean handleOutput(MessageContext contextthrows SOAPFaultException {
        try {
            // get the CallContext
            CallContext ctx = Current.getCallContext();
            Map ctxData = ctx.getContextData();

            // read userName and password from the CallContext
            String userName = (StringctxData.get(USER_NAME_KEY);
            String password = (StringctxData.get(PASSWORD_KEY);

            // test if userName and password exist
            if(userName == null || password == null) {
                throw new JAXRPCException("username or password null");
            }

            SOAPMessageContext messageContext = (SOAPMessageContextcontext;
            SOAPFactory factory = SOAPFactory.newInstance();

            // gets the SOAP header
            SOAPHeader header =  messageContext.getMessage().getSOAPPart().getEnvelope().getHeader();

            // adds the authetication header
            Name name = factory.createName(Const.AUTH_HEADER.getLocalPart(), null, Const.AUTH_HEADER.getNamespaceURI());
            SOAPHeaderElement element = header.addHeaderElement(name);

            SOAPElement usernameTokenElement = element.addChildElement(Const.USERNAME_TOKEN.getLocalPart(), null, Const.USERNAME_TOKEN.getNamespaceURI());

            SOAPElement userNameElement = usernameTokenElement.addChildElement(Const.USER_NAME.getLocalPart(), null, Const.USER_NAME.getNamespaceURI());
            userNameElement.addTextNode(userName);
            SOAPElement passwordElement = usernameTokenElement.addChildElement(Const.PASSWORD.getLocalPart(), null, Const.PASSWORD.getNamespaceURI());
            passwordElement.addTextNode(password);
            return true;

        catch (Exception e) {
            throw new JAXRPCException(e);
        }
    }
}

Then call the handler similar to this:

ClientService m_serviceClient = ServiceClient.create(serverURL + m_serviceWSDLPath);

//insert handler
m_serviceClient.getHandlers().insert(new ClientHandler());

//create proxy
m_PEWS = (ProcessEngineService)m_serviceClient.createProxy(ProcessEngineService.class);