Red Hat Training

A Red Hat training course is available for Red Hat Fuse

Chapter 5. Securing the Camel CXF Component

Abstract

This chapter explains how to enable SSL/TLS security on a Camel CXF endpoint, using the Camel CXF proxy demonstration as the starting point. The Camel CXF component enables you to add Apache CXF endpoints to your Apache Camel routes. This makes it possible to simulate a Web service in Apache Camel or you could interpose a route between a WS client and a Web service to perform additional processing (which is the case considered here).

5.1. The Camel CXF Proxy Demonstration

Overview

In order to explain how to secure a Camel CXF endpoint in OSGi, this tutorial builds on an example available from the standalone distribution of Apache Camel, the Camel CXF proxy demonstration. Figure 5.1, “Camel CXF Proxy Overview” gives an overview of how this demonstration works

Figure 5.1. Camel CXF Proxy Overview

camel cxf 01

The report incident Web service, which is implemented by the RealWebServiceBean, receives details of an incident (for example, a traffic accident) and returns a tracking code to the client. Instead of sending its requests directly to the real Web service, however, the WS client connects to a Camel CXF endpoint, which is interposed between the WS client and the real Web service. The Apache Camel route performs some processing on the WSDL message (using the enrichBean) before forwarding it to the real Web service.

Warning

If you enable SSL/TLS security, you must ensure that you explicitly disable the SSLv3 protocol, in order to safeguard against the Poodle vulnerability (CVE-2014-3566). For more details, see Disabling SSLv3 in JBoss Fuse 6.x and JBoss A-MQ 6.x.

Modifications

In order to demonstrate how to enable SSL/TLS on a Camel CXF endpoint in the context of OSGi, this chapter contains instructions on how to modify the basic demonstration as follows:

  1. SSL/TLS security is enabled on the connection between the WS client and the Camel CXF endpoint.
  2. The Apache Camel route and the RealWebServiceBean bean are both deployed into the OSGi container.

Obtaining the demonstration code

The Camel CXF proxy demonstration is available only from the standalone distribution of Apache Camel, which is included in the InstallDir/extras directory. Using a standard archive utility, expand the Camel archive file and extract the contents to a convenient location on your filesystem.

Assuming that you have installed Apache Camel in CamelInstallDir, you can find the Camel CXF proxy demonstration in the following directory:

CamelInstallDir/examples/camel-example-cxf-proxy

Obtaining the sample certificates

This demonstration needs X.509 certificates. In a real deployment, you should generate these certificates yourself using a private certificate authority. For this demonstration, however, we use some sample certificates from the Apache CXF wsdl_first_http example. This demonstration is available from the standalone distribution of Apache CXF, which is included in the InstallDir/extras directory. Using a standard archive utility, expand the CXF archive file and extract the contents to a convenient location on your filesystem.

Assuming that you have installed Apache CXF in CXFInstallDir, you can find the wsdl_first_http demonstration in the following directory:

CXFInstallDir/samples/wsdl_first_http

Physical part of the WSDL contract

The physical part of the WSDL contract refers to the wsdl:service and wsdl:port elements. These elements specify the transport details that are needed to connect to a specific Web services endpoint. For the purposes of this demonstration, this is the most interesting part of the contract and it is shown in Example 5.1, “The ReportIncidentEndpointService WSDL Service”.

Example 5.1. The ReportIncidentEndpointService WSDL Service

<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    ...
	xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
	targetNamespace="http://reportincident.example.camel.apache.org">
    ...
    <!-- Service definition -->
    <wsdl:service name="ReportIncidentEndpointService">
        <wsdl:port name="ReportIncidentEndpoint" binding="tns:ReportIncidentBinding">
            <soap:address location="http://localhost:9080/camel-example-cxf-proxy/webservices/incident"/>
        </wsdl:port>
    </wsdl:service>

</wsdl:definitions>
Note

The address URL appearing in the WSDL contract (the value of the soap:address element’s location attribute) is not important here, because the application code overrides the default value of the address URL.

WSDL addressing details

A WS client needs three pieces of information to connect to a WSDL service: the WSDL service name, the WSDL port name, and the address URL of the Web service. The following addressing details are used to connect to the proxy Web service and to the real Web service in this example:

WSDL service name

The full QName of the WSDL service is as follows:

{http://reportincident.example.camel.apache.org}ReportIncidentEndpointService
WSDL port name

The full QName of the WSDL port is as follows:

{http://reportincident.example.camel.apache.org}ReportIncidentEndpoint
Address URL

The address URL of the proxy Web service endpoint (which uses the HTTPS protocol) is as follows:

https://localhost:9080/camel-example-cxf-proxy/webservices/incident
Note

The preceding address is specified when the reportIncident bean is created using a cxf:cxfEndpoint element in the bundle’s Spring configuration file, src/main/resources/META-INF/spring/camel-config.xml.

The address URL of the real Web service endpoint (using the HTTP protocol) is as follows:

http://localhost:9081/real-webservice
Note

The preceding address is specified when the realWebService bean is created in the bundle’s Spring configuration file, src/main/resources/META-INF/spring/camel-config.xml.

5.2. Securing the Web Services Proxy

Overview

This section explains how to enable SSL/TLS security on the Camel CXF endpoint, which acts as a proxy for the real Web service. Assuming that you already have the X.509 certificates available, all that is required is to add a block of configuration data to the Spring configuration file (where the configuration data is contained in a httpj:engine-factory element). There is just one slightly subtle aspect to this, however: you need to understand how the Camel CXF endpoint gets associated with the SSL/TLS configuration details.

Implicit configuration

A WS endpoint can be configured by creating the endpoint in Spring and then configuring SSL/TLS properties on its Jetty container. The configuration can be somewhat confusing, however, for the following reason: the Jetty container (which is configured by a httpj:engine-factory element in Spring) does not explicitly reference the WS endpoints it contains and the WS endpoints do not explicitly reference the Jetty container either. The connection between the Jetty container and its contained endpoints is established implicitly, in that they are both configured to use the same TCP port, as illustrated by WS Endpoint Implicitly Configured by httpj:engine-factory.

WS Endpoint Implicitly Configured by httpj:engine-factory

Element

camel cxf 03

The connection between the Web service endpoint and the httpj:engine-factory element is established as follows:

  1. The Spring container loads and parses the file containing the httpj:engine-factory element.
  2. When the httpj:engine-factory bean is created, a corresponding entry is created in the registry, storing a reference to the bean. The httpj:engine-factory bean is also used to initialize a Jetty container that listens on the specified TCP port.
  3. When the WS endpoint is created, it scans the registry to see if it can find a httpj:engine-factory bean with the same TCP port as the TCP port in the endpoint’s address URL.
  4. If one of the beans matches the endpoint’s TCP port, the WS endpoint installs itself into the corresponding Jetty container. If the Jetty container has SSL/TLS enabled, the WS endpoint shares those security settings.

Steps to add SSL/TLS security to the Jetty container

To add SSL/TLS security to the Jetty container, thereby securing the WS proxy endpoint, perform the following steps:

Add certificates to the bundle resources

The certificates used in this demonstration are taken from a sample in the Apache CXF 3.1.11.fuse-720057-redhat-00001 product. If you install the standalone version of Apache CXF (available in the InstallDir/extras/ directory), you will find the sample certificates in the CXFInstallDir/samples/wsdl_first_https/src/main/config directory.

Copy the clientKeystore.jks and serviceKeystore.jks keystores from the CXFInstallDir/samples/wsdl_first_https/src/main/config directory to the CamelInstallDir/examples/camel-example-cxf-proxy/src/main/resources/certs directory (you must first create the certs sub-directory).

Modify POM to switch off resource filtering

Including the certificates directly in the bundle as resource is the most convenient way to deploy them. But when you deploy certificates as resources in a Maven project, you must remember to disable Maven resource filtering, which corrupts binary files.

To disable filtering of .jks files in Maven, open the project POM file, CamelInstallDir/examples/camel-example-cxf-proxy/pom.xml, with a text editor and add the following resources element as a child of the build element:

<?xml version="1.0" encoding="UTF-8"?>
...
<project ...>
  ...
  <build>
    <plugins>
      ...
    </plugins>

    <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <excludes> <exclude>/.jks</exclude> </excludes> </resource> <resource> <directory>src/main/resources</directory> <filtering>false</filtering> <includes> <include>/.jks</include> </includes> </resource> </resources>
  </build>

</project>

Instantiate the CXF Bus

You should instantiate the CXF bus explicitly in the Spring XML (this ensures that it will be available to the Jetty container, which is instantiated by the httpj:engine-factory element in the next step). Edit the camel-config.xml file in the src/main/resources/META-INF/spring directory, adding the cxfcore:bus element as a child of the beans element, as follows:

<beans ... >
    ...
    <cxfcore:bus/>
    ...
</beans>
Note

The cxfcore: namespace prefix will be defined in a later step.

Add the httpj:engine-factory element to Spring

configuration

To configure the Jetty container that listens on TCP port 9080 to use SSL/TLS security, edit the camel-config.xml file in the src/main/resources/META-INF/spring directory, adding the httpj:engine-factory element as shown in Example 5.2, “httpj:engine-factory Element with SSL/TLS Enabled”.

In this example, the required attribute of the sec:clientAuthentication element is set to false, which means that a connecting client is not required to present an X.509 certificate to the server during the SSL/TLS handshake (although it may do so, if it has such a certificate).

Example 5.2. httpj:engine-factory Element with SSL/TLS Enabled

<beans ... >
    ...
    <httpj:engine-factory bus="cxf">
      <httpj:engine port="${proxy.port}">
        <httpj:tlsServerParameters secureSocketProtocol="TLSv1">
          <sec:keyManagers keyPassword="skpass">
            <sec:keyStore resource="certs/serviceKeystore.jks" password="sspass" type="JKS"/>
          </sec:keyManagers>
          <sec:trustManagers>
            <sec:keyStore resource="certs/serviceKeystore.jks" password="sspass" type="JKS"/>
          </sec:trustManagers>
          <sec:cipherSuitesFilter>
            <sec:include>.*_WITH_3DES_.*</sec:include>
            <sec:include>.*_WITH_DES_.*</sec:include>
            <sec:exclude>.*_WITH_NULL_.*</sec:exclude>
            <sec:exclude>.*_DH_anon_.*</sec:exclude>
          </sec:cipherSuitesFilter>
          <sec:clientAuthentication want="true" required="false"/>
        </httpj:tlsServerParameters>
      </httpj:engine>
    </httpj:engine-factory>

</beans>
Important

You must set secureSocketProtocol to TLSv1 on the server side, in order to protect against the Poodle vulnerability (CVE-2014-3566)

Define the cxfcore:, sec: and httpj: prefixes

Define the cxfcore:, sec: and httpj: namespace prefixes, which appear in the definitions of the cxfcore:bus element and the httpj:engine-factory element, by adding the following highlighted lines to the beans element in the camel-config.xml file:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:camel="http://camel.apache.org/schema/spring"
       xmlns:cxf="http://camel.apache.org/schema/cxf"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:cxfcore="http://cxf.apache.org/core"
       xmlns:sec="http://cxf.apache.org/configuration/security"
       xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
       http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
       http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
       http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd
       ">
Note

It is essential to specify the locations of the http://cxf.apache.org/configuration/security schema and the http://cxf.apache.org/transports/http-jetty/configuration schema in the xsi:schemaLocation attribute. These will not automatically be provided by the OSGi container.

Modify proxy address URL to use HTTPS

The proxy endpoint at the start of the Apache Camel route is configured by the cxf:cxfEndpoint element in the camel-config.xml file. By default, this proxy endpoint is configured to use the HTTP protocol. You must modify the address URL to use the secure HTTPS protocol instead, however. In the camel-config.xml file, edit the address attribute of the cxf:cxfEndpoint element, replacing the http: prefix by the https: prefix, as shown in the following fragment:

<beans ...>
    ...
    <cxf:cxfEndpoint id="reportIncident"
                     address="https://localhost:${proxy.port}/camel-example-cxf-proxy/webservices/incident"
                     endpointName="s:ReportIncidentEndpoint"
                     serviceName="s:ReportIncidentEndpointService"
                     wsdlURL="etc/report_incident.wsdl"
                     xmlns:s="http://reportincident.example.camel.apache.org"/>
    ...
</beans>

Notice also that the address URL is configured to use the TCP port, ${proxy.port} (which has the value 9080 by default). This TCP port value is the same as the value set for the Jetty container (configured by the http:engine-factory element), thus ensuring that this endpoint is deployed into the Jetty container. The attributes of the cxf:cxfEndpoint specify the WSDL addressing details as described in the section called “WSDL addressing details”:

serviceName
Specifies the WSDL service name.
endpointName
Specifies the WSDL port name.
address
Specifies the address URL of the proxy Web service.

5.3. Deploying the Apache Camel Route

Overview

The Maven POM file in the basic Camel CXF proxy demonstration is already configured to generate an OSGi bundle. Hence, after building the demonstration using Maven, the demonstration bundle (which contains the Apache Camel route and the RealWebServicesBean bean) is ready for deployment into the OSGi container.

Prerequisites

Before deploying the Apache Camel route into the OSGi container, you must configure the proxy Web service to use SSL/TLS security, as described in the previous section, Section 5.2, “Securing the Web Services Proxy”.

Steps to deploy the Camel route

To deploy the Web services proxy demonstration into the OSGi container, perform the following steps:

Build the demonstration

Use Maven to build and install the demonstration as an OSGi bundle. Open a command prompt, switch the current directory to CamelInstallDir/examples/camel-example-cxf-proxy, and enter the following command:

mvn install -Dmaven.test.skip=true

Start the OSGi container

If you have not already done so, start up the Karaf console (and container instance) by entering the following command in a new command prompt:

./fuse

Install the required features

The camel-cxf feature, which defines the bundles required for the Camel/CXF component, is not installed by default. To install the camel-cxf feature, enter the following console command:

JBossFuse:karaf@root> features:install camel-cxf

You also need the camel-http feature, which defines the bundles required for the Camel/HTTP component. To install the camel-http feature, enter the following console command:

JBossFuse:karaf@root> features:install camel-http

Deploy the bundle

Deploy the camel-example-cxf-proxy bundle, by entering the following console command:

JBossFuse:karaf@root> install -s mvn:org.apache.camel/camel-example-cxf-proxy/2.21.0.fuse-720050-redhat-00001
Note

In this case, it is preferable to deploy the bundle directly using install, rather than using hot deploy, so that you can see the bundle output on the console screen.

If you have any difficulty using the mvn URL handler, see olink:ESBOSGiGuide/UrlHandlers-Maven for details of how to set it up.

Check the console output

After the bundle is successfully deployed, you should see output like the following in the console window:

JBossFuse:karaf@root> Starting real web service...
Started real web service at: http://localhost:9081/real-webservice

5.4. Securing the Web Services Client

Overview

In the basic Camel CXF proxy demonstration, the Web services client is actually implemented as a JUnit test under the src/test directory. This means that the client can easily be run using the Maven command, mvn test. To enable SSL/TLS security on the client, the Java implementation of the test client is completely replaced and a Spring file, containing the SSL/TLS configuration, is added to the src/test/resources/META-INF/spring directory. Before describing the steps you need to perform to set up the client, this section explains some details of the client’s Java code and Spring configuration.

Implicit configuration

Apart from changing the URL scheme on the endpoint address to https:, most of the configuration to enable SSL/TLS security on a client proxy is contained in a http:conduit element in Spring configuration. The way in which this configuration is applied to the client proxy, however, is potentially confusing, for the following reason: the http:conduit element does not explicitly reference the client proxy and the client proxy does not explicitly reference the http:conduit element. The connection between the http:conduit element and the client proxy is established implicitly, in that they both reference the same WSDL port, as illustrated by Client Proxy Implicitly Configured by http:conduit.

Client Proxy Implicitly Configured by http:conduit

Element

camel cxf 02

The connection between the client proxy and the http:conduit element is established as follows:

  1. The client loads and parses the Spring configuration file containing the http:conduit element.
  2. When the http:conduit bean is created, a corresponding entry is created in the registry, which stores a reference to the bean under the specified WSDL port name (where the name is stored in QName format).
  3. When the JAX-WS client proxy is created, it scans the registry to see if it can find a http:conduit bean associated with the proxy’s WSDL port name. If it finds such a bean, it automatically injects the configuration details into the proxy.

Certificates needed on the client side

The client is configured with the following clientKeystore.jks keystore file from the src/main/resources/certs directory. This keystore contains two entries, as follows:

Trusted cert entry
A trusted certificate entry containing the CA certificate that issued and signed both the server certificate and the client certificate.
Private key entry
A private key entry containing the client’s own X.509 certificate and private key. In fact, this certificate is not strictly necessary to run the current example, because the server does not require the client to send a certificate during the TLS handshake (see Example 5.2, “httpj:engine-factory Element with SSL/TLS Enabled”).

Loading Spring definitions into the client

The example client is not deployed directly into a Spring container, but it requires some Spring definitions in order to define a secure HTTP conduit. So how can you create the Spring definitions without a Spring container? It turns out that it is easy to read Spring definitions into a Java-based client using the org.apache.cxf.bus.spring.SpringBusFactory class.

The following code shows how to read Spring definitions from the file, META-INF/spring/cxf-client.xml, and create an Apache CXF Bus object that incorporates those definitions:

// Java
import org.apache.cxf.bus.spring.SpringBusFactory;
...
protected void startCxfBus() throws Exception {
    bf = new SpringBusFactory();
    Bus bus = bf.createBus("META-INF/spring/cxf-client.xml");
    bf.setDefaultBus(bus);
}

Creating the client proxy

In principle, there are several different ways of creating a WSDL proxy: you could use the JAX-WS API to create a proxy based on the contents of a WSDL file; you could use the JAX-WS API to create a proxy without a WSDL file; or you could use the Apache CXF-specific class, JaxWsProxyFactoryBean, to create a proxy.

For this SSL/TLS client, the most convenient approach is to use the JAX-WS API to create a proxy without using a WSDL file, as shown in the following Java sample:

// Java
import javax.xml.ws.Service;
import org.apache.camel.example.reportincident.ReportIncidentEndpoint;
...
// create the webservice client and send the request
Service s = Service.create(SERVICE_NAME);
s.addPort(
    PORT_NAME,
    "http://schemas.xmlsoap.org/soap/",
    ADDRESS_URL
  );
ReportIncidentEndpoint client =
  s.getPort(PORT_NAME, ReportIncidentEndpoint.class);
Note

In this example, you cannot use the JaxWsProxyFactoryBean approach to create a proxy, because a proxy created in this way fails to find the HTTP conduit settings specified in the Spring configuration file.

The SERVICE_NAME and PORT_NAME constants are the QNames of the WSDL service and the WSDL port respectively, as defined in Example 5.1, “The ReportIncidentEndpointService WSDL Service”. The ADDRESS_URL string has the same value as the proxy Web service address and is defined as follows:

private static final String ADDRESS_URL =
  "https://localhost:9080/camel-example-cxf-proxy/webservices/incident";

In particular, note that the address must be defined with the URL scheme, https, which selects HTTP over SSL/TLS.

Steps to add SSL/TLS security to the client

To define a JAX-WS client with SSL/TLS security enabled, perform the following steps:

Create the Java client as a test case

Example 5.3, “ReportIncidentRoutesTest Java client” shows the complete code for a Java client that is implemented as a JUnit test case. This client replaces the existing test, ReportIncidentRoutesTest.java, in the src/test/java/org/apache/camel/example/reportincident sub-directory of the examples/camel-example-cxf-proxy demonstration.

To add the client to the CamelInstallDir/examples/camel-example-cxf-proxy demonstration, go to the src/test/java/org/apache/camel/example/reportincident sub-directory, move the existing ReportIncidentRoutesTest.java file to a backup location, then create a new ReportIncidentRoutesTest.java file and paste the code from Example 5.3, “ReportIncidentRoutesTest Java client” into this file.

Example 5.3. ReportIncidentRoutesTest Java client

// Java
package org.apache.camel.example.reportincident;

import org.apache.camel.spring.Main;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.junit.Test;

import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBusFactory;
import org.apache.camel.example.reportincident.ReportIncidentEndpoint;
import org.apache.camel.example.reportincident.ReportIncidentEndpointService;

import static org.junit.Assert.assertEquals;

/**
 * Unit test of our routes
 */
public class ReportIncidentRoutesTest {

    private static final QName SERVICE_NAME
        = new QName("http://reportincident.example.camel.apache.org", "ReportIncidentEndpointService");

    private static final QName PORT_NAME =
        new QName("http://reportincident.example.camel.apache.org", "ReportIncidentEndpoint");

    private static final String WSDL_URL = "file:src/main/resources/etc/report_incident.wsdl";

    // should be the same address as we have in our route
    private static final String ADDRESS_URL = "https://localhost:9080/camel-example-cxf-proxy/webservices/incident";

    protected SpringBusFactory bf;

    protected void startCxfBus() throws Exception {
        bf = new SpringBusFactory();
        Bus bus = bf.createBus("META-INF/spring/cxf-client.xml");
        bf.setDefaultBus(bus);
    }

    @Test
    public void testRendportIncident() throws Exception {
        startCxfBus();
        runTest();
    }

    protected void runTest() throws Exception {

        // create input parameter
        InputReportIncident input = new InputReportIncident();
        input.setIncidentId("123");
        input.setIncidentDate("2008-08-18");
        input.setGivenName("Claus");
        input.setFamilyName("Ibsen");
        input.setSummary("Bla");
        input.setDetails("Bla bla");
        input.setEmail("davsclaus@apache.org");
        input.setPhone("0045 2962 7576");

        // create the webservice client and send the request
        Service s = Service.create(SERVICE_NAME);
        s.addPort(PORT_NAME, "http://schemas.xmlsoap.org/soap/", ADDRESS_URL);
        ReportIncidentEndpoint client = s.getPort(PORT_NAME, ReportIncidentEndpoint.class);

        OutputReportIncident out = client.reportIncident(input);

        // assert we got a OK back
        assertEquals("OK;456", out.getCode());
    }
}

Add the http:conduit element to Spring configuration

Example 5.4, “http:conduit Element with SSL/TLS Enabled” shows the Spring configuration that defines a http:conduit element for the ReportIncidentEndpoint WSDL port. The http:conduit element is configured to enable SSL/TLS security for any client proxies that use the specified WSDL port.

To add the Spring configuration to the client test case, create the src/test/resources/META-INF/spring sub-directory, use your favorite text editor to create the file, cxf-client.xml, and then paste the contents of Example 5.4, “http:conduit Element with SSL/TLS Enabled” into the file.

Example 5.4. http:conduit Element with SSL/TLS Enabled

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cxf="http://camel.apache.org/schema/cxf"
       xmlns:sec="http://cxf.apache.org/configuration/security"
       xmlns:http="http://cxf.apache.org/transports/http/configuration"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
       http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
       http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
       ">

  <http:conduit name="{http://reportincident.example.camel.apache.org}ReportIncidentEndpoint.http-conduit">
    <http:tlsClientParameters disableCNCheck="true" secureSocketProtocol="TLSv1">
      <sec:keyManagers keyPassword="ckpass">
          <sec:keyStore password="cspass" type="JKS"
          resource="certs/clientKeystore.jks" />
      </sec:keyManagers>
      <sec:trustManagers>
          <sec:keyStore password="cspass" type="JKS"
          resource="certs/clientKeystore.jks" />
      </sec:trustManagers>
      <sec:cipherSuitesFilter>
        <sec:include>.*_WITH_3DES_.*</sec:include>
        <sec:include>.*_WITH_DES_.*</sec:include>
        <sec:exclude>.*WITH_NULL.</sec:exclude>*
        <sec:exclude>.*DH_anon.</sec:exclude>*
      </sec:cipherSuitesFilter>
    </http:tlsClientParameters>
   </http:conduit>

</beans>

Please note the following points about the preceding configuration:

  • The http: and sec: namespace prefixes are needed to define the http:conduit element. In the xsi:schemaLocation element, it is also essential to specify the locations of the corresponding http://cxf.apache.org/configuration/security and http://cxf.apache.org/transports/http/configuration namespaces.
  • The disableCNCheck attribute of the http:tlsClientParameters element is set to true. This means that the client does not check whether the Common Name in the server’s X.509 certificate matches the server hostname. For more details, see Appendix A, Managing Certificates.

    Important

    Disabling the CN check is not recommended in a production deployment.

  • In the sec:keystore elements, the certificate locations are specified using the resource attribute, which finds the certificates on the classpath. When Maven runs the test, it automatically makes the contents of src/main/resources available on the classpath, so that the certificates can be read from the src/main/resources/certs directory.

    Note

    You also have the option of specifying a certificate location using the file attribute, which looks in the filesystem. But the resource attribute is more suitable for use with applications packaged in bundles.

  • The sec:cipherSuitesFilter element is configured to exclude cipher suites matching .*WITH_NULL.\* and .*DH_anon.\*. These cipher suites are effectively incomplete and are not intended for normal use.

    Important

    It is recommended that you always exclude the ciphers matching .*WITH_NULL.\* and .*DH_anon.\*.

  • The secureSocketProtocol attribute should be set to TLSv1, to match the server protocol and to ensure that the SSLv3 protocol is not used (POODLE security vulnerability (CVE-2014-3566)).

Run the client

Because the client is defined as a test case, you can run the client using the standard Maven test goal. To run the client, open a new command window, change directory to CamelInstallDir/examples/camel-example-cxf-proxy, and enter the following Maven command:

mvn test

If the test runs successfully, you should see the following output in the OSGi console window:

Incident was 123, changed to 456

Invoked real web service: id=456 by Claus Ibsen