Wednesday, August 11, 2010

Using WS-Security with RiftSaw and JBossWS-CXF: Part 1 – Securing the BPEL process

In these posts we will explain how to add security to a BPEL process deployed in RiftSaw when using jbossws-cxf. This first post will explore how to make a BPEL process secure. To demonstrate how to achieve this, we will use the secure_service quickstart example, included in the RiftSaw distribution.

When making a standard JAX-WS service secure, jbossws-cxf simply requires a CXF based configuration file to be bundled with the deployed service [1]. This file is called jbossws-cxf.xml, and for our example, this would have the contents:

<beans xmlns='http://www.springframework.org/schema/beans' 
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' 
  xmlns:beans='http://www.springframework.org/schema/beans' 
  xmlns:jaxws='http://cxf.apache.org/jaxws' 
  xsi:schemaLocation='http://cxf.apache.org/core 
    http://cxf.apache.org/schemas/core.xsd 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
    http://cxf.apache.org/jaxws 
    http://cxf.apache.org/schemas/jaxws.xsd'> 
   
  <bean id="UsernameTokenSign_Request" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> 
    <constructor-arg> 
      <map> 
        <entry key="action" value="UsernameToken Timestamp Signature"/> 
        <entry key="passwordType" value="PasswordDigest"/> 
        <entry key="user" value="serverx509v1"/> 
        <entry key="passwordCallbackClass" value="org.jboss.test.ws.jaxws.samples.wsse.ServerUsernamePasswordCallback"/> 
        <entry key="signaturePropFile" value="etc/Server_SignVerf.properties"/> 
        <entry key="signatureKeyIdentifier" value="DirectReference"/> 
      </map> 
    </constructor-arg> 
  </bean> 
   
  <bean id="UsernameTokenSign_Response" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> 
    <constructor-arg> 
      <map> 
        <entry key="action" value="UsernameToken Timestamp Signature"/> 
        <entry key="passwordType" value="PasswordText"/> 
        <entry key="user" value="serverx509v1"/> 
        <entry key="passwordCallbackClass" value="org.jboss.test.ws.jaxws.samples.wsse.ServerUsernamePasswordCallback"/> 
        <entry key="signaturePropFile" value="etc/Server_Decrypt.properties"/> 
        <entry key="signatureKeyIdentifier" value="DirectReference"/> 
        <entry key="signatureParts" value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/> 
      </map> 
    </constructor-arg> 
  </bean> 
 
  <jaxws:endpoint 
    id='SecureHelloWorldWS' 
    address='http://@jboss.bind.address@:8080/Quickstart_bpel_secure_serviceWS' 
    implementor='@provider@'> 
    <jaxws:inInterceptors> 
        <ref bean="UsernameTokenSign_Request"/> 
        <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/> 
    </jaxws:inInterceptors> 
    <jaxws:outInterceptors> 
        <ref bean="UsernameTokenSign_Response"/> 
        <bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/> 
    </jaxws:outInterceptors> 
  </jaxws:endpoint> 

</beans>

To make the BPEL process secure, this file has to be included alongside the BPEL deployment descriptor and process at the top level of the BPEL deployment. This particular configuration uses UsernameToken and digital signature authentication on both the request and response.

The only difference between the contents of this file, and one that would be deployed with a JAX-WS service, is the implementor attribute on the jaxws:endpoint element. In the file above, the value of this attribute is @provider@. In a standard JAX-WS configuration, this value would be the class name implementing the JAX-WS service. The reason RiftSaw uses this alternative value, is that the class implementing the JAX-WS service is not known until deployment time, as it is dynamically created, and so it's class name will be substituted during deployment.

As you will note, the configuration references some property files in a relative sub-folder called etc. These property files also reference some keystore files stored in another relative sub-folder called keystore. Both of these relative sub-folders simply need to be stored at the top level of the BPEL deployment jar.

The configuration also defines a passwordCallbackClass, which must specify a class that implements the javax.security.auth.callback.CallbackHandler interface. In the secure_service example, this class is bundled with the BPEL deployment jar. However this property can reference any implementation that may already exist within the JBossAS server.

So to summarize, securing a BPEL process only requires the addition of a jbossws-cxf configuration file with supporting property and keystore information, and access to an appropriate CallbackHandler implementation.

[1] http://community.jboss.org/wiki/Jbossws-stackcxfUserGuide#WSSecurity