IBM FileNet P8, Version 5.2.1            

Creating the WS-Security Header

Process Engine Web Service uses WS-Security to pass authentication information, carried as plaintext in a SOAP header. Currently, the supported SOAP headers are the UsernameToken and the Kerberos BinarySecurityToken. These headers need to be present in every SOAP request, and need to be set for your toolkit before you generate source from the WSDL. The Username and Password values from the UsernameToken are authenticated by using the (supported) enterprise directory service.

Use SOAP over HTTPS (SSL) to secure the authentication data. Refer to Setting up Content Platform Engine and client transport SSL security for instructions.

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 that you are using. The following examples are for .NET and JAX-WS clients.

.NET

For WSE3.0, for the custom security policy assertion to attach a WS-Security SOAP header to the client's outgoing SOAP message, see the following Microsoft MSDN article: How to: Create a Custom Policy Assertion that Secures SOAP Messages. The following sample code illustrates the implementation of SecurityPolicyAssertion:

using System;
using System.Net;
using System.Collections.Generic;
using System.Text;
using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Design;
using Microsoft.Web.Services3.Security.Tokens;
using Microsoft.Web.Services3.Security;
namespace PE_C_Sharp_solution
{
    internal class SoapSecurityRequestFilter : SendSecurityFilter
    {
        private String peUsername;
        private String pePassword;
        private Boolean theCustomCredentialFlag;
        private Boolean theKerberosFlag;
        private String theSPN;

        internal SoapSecurityRequestFilter(
                            SecurityPolicyAssertion assert)
            : base(assert.ClientActor, true)
        {
        }
        internal SoapSecurityRequestFilter(
                    SecurityPolicyAssertion assert,
                    String peUsername, String pePassword, 
                    Boolean theCustomCredentialFlag, 
                    Boolean theKerberosFlag, string theSPN)
            : base(assert.ClientActor, true)
        {
            this.peUsername = peUsername;
            this.pePassword = pePassword ;
            this.theCustomCredentialFlag = theCustomCredentialFlag;
            this.theKerberosFlag = theKerberosFlag;
            this.theSPN = theSPN;
        }
        public override void SecureMessage(
                            SoapEnvelope envelope,
                            Security security)
        {
            /**
             * Added to test the support for the custom authentication framework.
             * This is a very simple custom authentication assuming that Content Platform Engine
             * has been set up to do custom authentication given a name and password.
             * 
             * If Kerberos testing is desired, you may want to add the option
             * and instantiate a KerberosToken.
             */

            SecurityToken tok = null;

            if (theCustomCredentialFlag)
            {
                tok = new CustomBinaryToken(peUsername + "|" + pePassword);
                Console.WriteLine("Using Custom Authentication .. " + peUsername);
            }
            else if (!theKerberosFlag && pePassword != null && pePassword.Trim().Length > 0)
            {
                tok = new UsernameToken(peUsername, pePassword, PasswordOption.SendPlainText);
                Console.WriteLine("Using UsernameToken with " + peUsername);
            }
            else
                Console.WriteLine("Using Kerberos : " + theSPN);

            if(theKerberosFlag)
                tok = new KerberosToken(theSPN);           

            if (tok != null)
            {
                security.Tokens.Add(tok);
            }
            else
            {
                throw new Exception("No credentials were set: spn=" + theSPN + ", useKerberos=" +
                    (theKerberosFlag  ? "true" : "false"));
            }
             
            
        }

        public override SoapFilterResult ProcessMessage(
                            SoapEnvelope envelope)
        {

            // Disable 100-continue behaviour, to save on the unnecessary
            // round trip. Also turn off nagling.
            SoapContext ctx = SoapContext.Current;
            HttpWebRequest wreq = (HttpWebRequest)ctx.WebRequest;
            wreq.ServicePoint.Expect100Continue = false;
            wreq.ServicePoint.UseNagleAlgorithm = false;

            // Delegate to base (this will call SecureMessage above)
            return base.ProcessMessage(envelope);
        }

    }

    /**
     * Use this class to insert the WS-Security SOAP header containing
     * the authentication information. UserContext should be set with
     * some kind of security token.
     */
    internal class PESecurityAssertion : SecurityPolicyAssertion
    {
        private String peUsername;
        private String pePassword;
        private Boolean theCustomCredentialFlag;
        private Boolean theKerberosFlag;
        private String theSPN;

        internal PESecurityAssertion()
            : base()
        {
        }
        internal PESecurityAssertion(String peUsername, String pePassword, Boolean theCustomCredentialFlag, Boolean theKerberosFlag, string theSPN)
            : base()
        {
            this.peUsername = peUsername;
            this.pePassword = pePassword ;
            this.theCustomCredentialFlag = theCustomCredentialFlag;
            this.theKerberosFlag = theKerberosFlag;
            this.theSPN = theSPN;
        }

        public override SoapFilter CreateClientOutputFilter(
                                        FilterCreationContext ctx)
        {
           // return new SoapSecurityRequestFilter(this);
            return new SoapSecurityRequestFilter(this, peUsername, pePassword, theCustomCredentialFlag , theKerberosFlag, theSPN);
        }

        public override SoapFilter CreateClientInputFilter(
                                        FilterCreationContext ctx)
        {
            return null;
        }

        public override SoapFilter CreateServiceInputFilter(
                                        FilterCreationContext ctx)
        {
            return null;
        }

        public override SoapFilter CreateServiceOutputFilter(
                                        FilterCreationContext ctx)
        {
            return null;
        }
    }

}

The following code fragment illustrates how the SecurityPolicyAssertion is assigned to the proxy object:

Policy pePolicy = new Policy(
                                new PolicyAssertion[] 
                                {
                                    new PEAssertion(peRouter, peLocale),
                                    new PESecurityAssertion(peUsername,pePassword ,theCustomCredentialFlag,theKerberosFlag,theSPN)
                                }
                            );
peWSServicePort.SetPolicy(pePolicy);

JAX-WS clients

For JAX-WS clients, to attach WS-Security SOAP header, do the following actions:
  • Implement a javax.xml.ws.handler.soap.SOAPHandler class.
  • Set the handler chain for the binding of the service proxy object, as illustrated in the following sample.
public class PEWSClientHeaderHandler implements
                SOAPHandler<SOAPMessageContext> {

    private static final String AUTH_NS = "http://schemas.xmlsoap.org/ws/2002/12/secext";
    private static final String AUTH_PREFIX="wss";
        public PEWSClientHeaderHandler() {
        }
        
        public boolean handleFault(SOAPMessageContext smc)
        {
                return true;
        }

        public void close(MessageContext mc)
        {
        }
        public boolean handleMessage(SOAPMessageContext smc) {
                boolean direction = ((Boolean) smc
                                .get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY))
                                .booleanValue();

                String userName = (String) smc.get(Const.REQCONTEXT_USERNAME);
                String password = (String) smc.get(Const.REQCONTEXT_PASSWORD);
                String connectionPoint = (String) smc.get(Const.REQCONTEXT_CONNECTIONPOINT);
                String localeInfo = (String)smc.get(Const.REQCONTEXT_LOCALIZATION);
                String ceuri = (String)smc.get(Const.REQCONTEXT_BOOTSTRAP_CEURI);

                if (direction) {
                        try {
                                SOAPEnvelope envelope = smc.getMessage().getSOAPPart()
                                                .getEnvelope();
                                SOAPFactory soapFactory = SOAPFactory.newInstance();
                                
                                // WSSecurity <Security> header
                                SOAPElement wsSecHeaderElm = soapFactory.createElement(
                                                "Security",
                                                AUTH_PREFIX,
                                                AUTH_NS);
                                SOAPElement userNameTokenElm = soapFactory.createElement("UsernameToken",
                                                AUTH_PREFIX,
                                                AUTH_NS);
                                SOAPElement userNameElm = soapFactory.createElement("Username",
                                                AUTH_PREFIX,
                                                AUTH_NS);
                                userNameElm.addTextNode(userName);
                                
                                SOAPElement passwdElm = soapFactory.createElement("Password",
                                                AUTH_PREFIX,
                                                AUTH_NS);
                                passwdElm.addTextNode(password);

                                userNameTokenElm.addChildElement(userNameElm);
                                userNameTokenElm.addChildElement(passwdElm);
                                
                                // add child elements to the root element
                                wsSecHeaderElm.addChildElement(userNameTokenElm);

                                // create SOAPHeader instance for SOAP envelope
                                SOAPHeader sh = envelope.addHeader();

                                // add SOAP element for header to SOAP header object
                                sh.addChildElement(wsSecHeaderElm);
                                
                                // connectionPoint header
                                if (connectionPoint!=null)
                                {
                                        SOAPElement cpHeaderElm = soapFactory.createElement(
                                                        "Router",
                                                        "pe2004",
                                                        "http://www.filenet.com/ns/fnpe/2004/06/ws/schema");
                                        cpHeaderElm.addTextNode(connectionPoint);
                                        sh.addChildElement(cpHeaderElm);
                                }
                                
                                // locale
                                if (localeInfo !=null)
                                {
                                        SOAPElement localHeaderElm = soapFactory.createElement(
                                                        "Localization",
                                                        "pe2006",
                                                        "http://www.filenet.com/ns/fnpe/2006/07/ws/schema");
                                        localHeaderElm.addTextNode(localeInfo);
                                        sh.addChildElement(localHeaderElm);
                                }                       
                                
                                // bootstrap CEURI header -- just added for testing purpose
                                if (ceuri !=null)
                                {
                                        SOAPElement ceuriHeaderElm = soapFactory.createElement(
                                                        "filenet.pe.bootstrap.ceuri",
                                                        "pe2009",
                                                        "http://www.filenet.com/ns/fnpe/2009/05/ws/schema");
                                        ceuriHeaderElm.addTextNode(ceuri);
                                        sh.addChildElement(ceuriHeaderElm);
                                }
                        } catch (Exception ex) {
                                ex.printStackTrace();
                        }
                }
                return true;
        }

        public java.util.Set<QName> getHeaders() {
                return null;
        }
}

The following code fragment illustrates how the handler can be set in the handler chain for the binding of the proxy object:

ProcessEngineServiceProxy pewsServiceProxy = new ProcessEngineServiceProxy();
pewsServiceProxy._getDescriptor().setEndpoint(url);

// install the handler chain
BindingProvider bp = (BindingProvider) pewsServiceProxy._getDescriptor().getProxy();
Binding pewsBinding = bp.getBinding();
List<Handler> handlerChain = new java.util.ArrayList<Handler>();
PEWSClientHeaderHandler wsSecurity = new PEWSClientHeaderHandler();
handlerChain.add(wsSecurity);
pewsBinding.setHandlerChain(handlerChain);


Last updated: March 2016
ws_usage_headers.htm

© Copyright IBM Corporation 2016.