Red Hat Training

A Red Hat training course is available for Red Hat Fuse

4.3. Apache CXF WS-Security Implementation

Apache CXF features a WS-Security module that supports multiple configurations and is easily extendible. The system is based on interceptors that delegate to Apache WSS4J for the low level security operations. Interceptors can be configured in different ways, either through Spring configuration files or directly using Apache CXF client API. For more details, refer to the Apache CXF documentation.
Recent versions of Apache CXF introduced support for WS-Security Policy, which aims at moving most of the security configuration into the service contract (through policies), so that clients can easily be configured almost completely automatically from that. This way users do not need to manually deal with configuring or installing the required interceptors. The Apache CXF WS-Policy engine internally takes care of that.

4.3.1. WS-Security Policy Support

WS-SecurityPolicy describes the actions that are required to securely communicate with a service advertised in a given WSDL contract. The WSDL bindings and operations reference WS-Policy fragments with the security requirements to interact with the service. The WS-SecurityPolicy specification allows for specifying things like asymmetric and symmetric keys, using transports (https) for encryption, which parts or headers to encrypt or sign, whether to sign then encrypt or encrypt then sign, whether to include timestamps, and whether to use derived keys.
Some mandatory configuration elements are not covered by WS-SecurityPolicy because they are not meant to be public or part of the published endpoint contract. These include things such as keystore locations, usernames and passwords. Apache CXF allows configuring these elements either through Spring xml descriptors or using the client API or annotations. Below is the list of supported configuration properties:

Table 4.1. Supported Configuration Properties

Property Description
ws-security.username
The username used for UsernameToken policy assertions.
ws-security.password
The password used for UsernameToken policy assertions. If not specified, the callback handler is called.
ws-security.callback-handler
The WSS4J security CallbackHandler that is used to retrieve passwords for keystores and UsernameTokens.
ws-security.signature.properties
The properties file or object that contains the WSS4J properties for configuring the signature keystore and crypto objects.
ws-security.encryption.properties
The properties file or object that contains the WSS4J properties for configuring the encryption keystore and crypto objects.
ws-security.signature.username
The username or alias for the key in the signature keystore. If not specified, it uses the default alias set in the properties file. If that is also not set, and the keystore only contains a single key, that key is used.
ws-security.encryption.username
The username or alias for the key in the encryption keystore. If not specified, it uses the default alias set in the properties file. If that is also not set, and the keystore only contains a single key, that key is used. For the web service provider, the useReqSigCert keyword can be used to accept (encrypt to) any client whose public key is in the service's truststore (defined in ws-security.encryption.properties.)
ws-security.signature.crypto
Instead of specifying the signature properties, this can point to the full WSS4J Crypto object. This can allow easier programmatic configuration of the Crypto information.
ws-security.encryption.crypto
Instead of specifying the encryption properties, this can point to the full WSS4J Crypto object. This can allow easier programmatic configuration of the Crypto information.
Here is an example of configuration using the client API:
    Map<String, Object> ctx = ((BindingProvider)port).getRequestContext();
ctx.put("ws-security.encryption.properties", properties);
port.echoString("hello");    

For additional configuration details, refer to the Apache CXF documentation.

4.3.2. JBossWS Configuration Additions

In order for removing the need of Spring on server side for setting up WS-Security configuration properties not covered by policies, the JBossWS integration allows for getting those pieces of information from a defined endpoint configuration. Endpoint configurations can include property declarations and endpoint implementations can be associated with a given endpoint configuration using the @EndpointConfig annotation.
<?xml version="1.0" encoding="UTF-8"?>
<jaxws-config xmlns="urn:jboss:jbossws-jaxws-config:4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:javaee="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="urn:jboss:jbossws-jaxws-config:4.0 schema/jbossws-jaxws-config_4_0.xsd">
  <endpoint-config>
    <config-name>Custom WS-Security Endpoint</config-name>
    <property>
      <property-name>ws-security.signature.properties</property-name>
      <property-value>bob.properties</property-value>
    </property>
    <property>
      <property-name>ws-security.encryption.properties</property-name>
      <property-value>bob.properties</property-value>
    </property>
    <property>
      <property-name>ws-security.signature.username</property-name>
      <property-value>bob</property-value>
    </property>
    <property>
      <property-name>ws-security.encryption.username</property-name>
      <property-value>alice</property-value>
    </property>
    <property>
      <property-name>ws-security.callback-handler</property-name>
      <property-value>org.jboss.test.ws.jaxws.samples.wsse.policy.basic.KeystorePasswordCallback</property-value>
    </property>
  </endpoint-config>
</jaxws-config>
import javax.jws.WebService;
import org.jboss.ws.api.annotation.EndpointConfig;
 
@WebService
(
   portName = "SecurityServicePort",
   serviceName = "SecurityService",
   wsdlLocation = "WEB-INF/wsdl/SecurityService.wsdl",
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wssecuritypolicy",
   endpointInterface = "org.jboss.test.ws.jaxws.samples.wsse.policy.basic.ServiceIface"
)
@EndpointConfig(configFile = "WEB-INF/jaxws-endpoint-config.xml", configName = "Custom WS-Security Endpoint")
public class ServiceImpl implements ServiceIface
{
   public String sayHello()
   {
      return "Secure Hello World!";
   }
}

4.3.3. Apache CXF Annotations

The JBossWS configuration additions allow for a descriptor approach to the WS-Security Policy engine configuration. If you prefer to provide the same information through an annotation approach, you can leverage the Apache CXF @org.apache.cxf.annotations.EndpointProperties annotation:
@WebService(
   ...
)
@EndpointProperties(value = {
      @EndpointProperty(key = "ws-security.signature.properties", value = "bob.properties"),
      @EndpointProperty(key = "ws-security.encryption.properties", value = "bob.properties"),
      @EndpointProperty(key = "ws-security.signature.username", value = "bob"),
      @EndpointProperty(key = "ws-security.encryption.username", value = "alice"),
      @EndpointProperty(key = "ws-security.callback-handler", value = "org.jboss.test.ws.jaxws.samples.wsse.policy.basic.KeystorePasswordCallback")
      }
)
public class ServiceImpl implements ServiceIface {
   ...
}