Menu Close
Settings Close

Language and Page Formatting Options

Chapter 1. Security for HTTP-Compatible Bindings

Abstract

This chapter describes the security features supported by the Apache CXF HTTP transport. These security features are available to any Apache CXF binding that can be layered on top of the HTTP transport.

Overview

This section describes how to configure the HTTP transport to use SSL/TLS security, a combination usually referred to as HTTPS. In Apache CXF, HTTPS security is configured by specifying settings in XML configuration files.

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.

The following topics are discussed in this chapter:

Generating X.509 certificates

A basic prerequisite for using SSL/TLS security is to have a collection of X.509 certificates available to identify your server applications and, optionally, to identify your client applications. You can generate X.509 certificates in one of the following ways:

Note

The HTTPS protocol mandates a URL integrity check, which requires a certificate’s identity to match the hostname on which the server is deployed. See Section 2.4, “Special Requirements on HTTPS Certificates” for details.

Certificate format

In the Java runtime, you must deploy X.509 certificate chains and trusted CA certificates in the form of Java keystores. See Chapter 3, Configuring HTTPS for details.

Enabling HTTPS

A prerequisite for enabling HTTPS on a WSDL endpoint is that the endpoint address must be specified as a HTTPS URL. There are two different locations where the endpoint address is set and both must be modified to use a HTTPS URL:

  • HTTPS specified in the WSDL contract—you must specify the endpoint address in the WSDL contract to be a URL with the https: prefix, as shown in Example 1.1, “Specifying HTTPS in the WSDL”.

    Example 1.1. Specifying HTTPS in the WSDL

    <wsdl:definitions name="HelloWorld"
                    targetNamespace="http://apache.org/hello_world_soap_http"
                    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" ... >
      ...
      <wsdl:service name="SOAPService">
        <wsdl:port binding="tns:Greeter_SOAPBinding"
                   name="SoapPort">
          <soap:address location="https://localhost:9001/SoapContext/SoapPort"/>
        </wsdl:port>
      </wsdl:service>
    </wsdl:definitions>

    Where the location attribute of the soap:address element is configured to use a HTTPS URL. For bindings other than SOAP, you edit the URL appearing in the location attribute of the http:address element.

  • HTTPS specified in the server code—you must ensure that the URL published in the server code by calling Endpoint.publish() is defined with a https: prefix, as shown in Example 1.2, “Specifying HTTPS in the Server Code”.

    Example 1.2. Specifying HTTPS in the Server Code

    // Java
    package demo.hw_https.server;
    import javax.xml.ws.Endpoint;
    
    public class Server {
      protected Server() throws Exception {
        Object implementor = new GreeterImpl();
        String address = "https://localhost:9001/SoapContext/SoapPort";
        Endpoint.publish(address, implementor);
      }
      ...
      }

HTTPS client with no certificate

For example, consider the configuration for a secure HTTPS client with no certificate, as shown in Example 1.3, “Sample HTTPS Client with No Certificate”.

Example 1.3. Sample HTTPS Client with No Certificate

<?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:sec="http://cxf.apache.org/configuration/security"
       xmlns:http="http://cxf.apache.org/transports/http/configuration"
       xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
       xsi:schemaLocation="...">

    <http:conduit name="{http://apache.org/hello_world_soap_http}SoapPort.http-conduit">
      <http:tlsClientParameters>
        <sec:trustManagers>
          <sec:keyStore type="JKS" password="password"
                        file="certs/truststore.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>

The preceding client configuration is described as follows:

The TLS security settings are defined on a specific WSDL port. In this example, the WSDL port being configured has the QName, {http://apache.org/hello_world_soap_http}SoapPort.

The http:tlsClientParameters element contains all of the client’s TLS configuration details.

The sec:trustManagers element is used to specify a list of trusted CA certificates (the client uses this list to decide whether or not to trust certificates received from the server side).

The file attribute of the sec:keyStore element specifies a Java keystore file, truststore.jks, containing one or more trusted CA certificates. The password attribute specifies the password required to access the keystore, truststore.jks. See Section 3.2.2, “Specifying Trusted CA Certificates for HTTPS”.

Note

Instead of the file attribute, you can specify the location of the keystore using either the resource attribute (where the keystore file is provided on the classpath) or the url attribute. In particular, the resource attribute must be used with applications that are deployed into an OSGi container. You must be extremely careful not to load the truststore from an untrustworthy source.

The sec:cipherSuitesFilter element can be used to narrow the choice of cipher suites that the client is willing to use for a TLS connection. See Chapter 4, Configuring HTTPS Cipher Suites for details.

HTTPS client with certificate

Consider a secure HTTPS client that is configured to have its own certificate. Example 1.4, “Sample HTTPS Client with Certificate” shows how to configure such a sample client.

Example 1.4. Sample HTTPS Client with Certificate

<?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:sec="http://cxf.apache.org/configuration/security"
 xmlns:http="http://cxf.apache.org/transports/http/configuration"
 xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
 xsi:schemaLocation="...">

  <http:conduit name="{http://apache.org/hello_world_soap_http}SoapPort.http-conduit">
    <http:tlsClientParameters>
      <sec:trustManagers>
          <sec:keyStore type="JKS" password="password"
               file="certs/truststore.jks"/>
      </sec:trustManagers>
      <sec:keyManagers keyPassword="password">
           <sec:keyStore type="JKS" password="password"
                file="certs/wibble.jks"/>
      </sec:keyManagers>
      <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>

    <bean id="cxf" class="org.apache.cxf.bus.CXFBusImpl"/>
</beans>

The preceding client configuration is described as follows:

The sec:keyManagers element is used to attach an X.509 certificate and a private key to the client. The password specified by the keyPasswod attribute is used to decrypt the certificate’s private key.

The sec:keyStore element is used to specify an X.509 certificate and a private key that are stored in a Java keystore. This sample declares that the keystore is in Java Keystore format (JKS).

The file attribute specifies the location of the keystore file, wibble.jks, that contains the client’s X.509 certificate chain and private key in a key entry. The password attribute specifies the keystore password which is required to access the contents of the keystore.

It is expected that the keystore file contains just one key entry, so it is not necessary to specify a key alias to identify the entry. If you are deploying a keystore file with multiple key entries, however, it is possible to specify the key in this case by adding the sec:certAlias element as a child of the http:tlsClientParameters element, as follows:

<http:tlsClientParameters>
    ...
    <sec:certAlias>CertAlias</sec:certAlias>
    ...
</http:tlsClientParameters>

For details of how to create a keystore file, see Section 2.5.3, “Use the CA to Create Signed Certificates in a Java Keystore”.

Note

Instead of the file attribute, you can specify the location of the keystore using either the resource attribute (where the keystore file is provided on the classpath) or the url attribute. In particular, the resource attribute must be used with applications that are deployed into an OSGi container. You must be extremely careful not to load the truststore from an untrustworthy source.

HTTPS server configuration

Consider a secure HTTPS server that requires clients to present an X.509 certificate. Example 1.5, “Sample HTTPS Server Configuration” shows how to configure such a server.

Example 1.5. Sample HTTPS Server Configuration

<?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:sec="http://cxf.apache.org/configuration/security"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xsi:schemaLocation="...">

  <httpj:engine-factory bus="cxf">
   <httpj:engine port="9001">
    <httpj:tlsServerParameters secureSocketProtocol="TLSv1">
      <sec:keyManagers keyPassword="password">
           <sec:keyStore type="JKS" password="password"
                file="certs/cherry.jks"/>
      </sec:keyManagers>
      <sec:trustManagers>
          <sec:keyStore type="JKS" password="password"
               file="certs/truststore.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="true"/>
    </httpj:tlsServerParameters>
   </httpj:engine>
  </httpj:engine-factory>

</beans>

The preceding server configuration is described as follows:

The bus attribute references the relevant CXF Bus instance. By default, a CXF Bus instance with the ID, cxf, is automatically created by the Apache CXF runtime.

On the server side, TLS is not configured for each WSDL port. Instead of configuring each WSDL port, the TLS security settings are applied to a specific TCP port, which is 9001 in this example. All of the WSDL ports that share this TCP port are therefore configured with the same TLS security settings.

The http:tlsServerParameters element contains all of the server’s TLS configuration details.

Important

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

The sec:keyManagers element is used to attach an X.509 certificate and a private key to the server. The password specified by the keyPasswod attribute is used to decrypt the certificate’s private key.

The sec:keyStore element is used to specify an X.509 certificate and a private key that are stored in a Java keystore. This sample declares that the keystore is in Java Keystore format (JKS).

The file attribute specifies the location of the keystore file, cherry.jks, that contains the client’s X.509 certificate chain and private key in a key entry. The password attribute specifies the keystore password, which is needed to access the contents of the keystore.

It is expected that the keystore file contains just one key entry, so it is not necessary to specify a key alias to identify the entry. If you are deploying a keystore file with multiple key entries, however, it is possible to specify the key in this case by adding the sec:certAlias element as a child of the http:tlsClientParameters element, as follows:

<http:tlsClientParameters>
    ...
    <sec:certAlias>CertAlias</sec:certAlias>
    ...
</http:tlsClientParameters>
Note

Instead of the file attribute, you can specify the location of the keystore using either the resource attribute or the url attribute. You must be extremely careful not to load the truststore from an untrustworthy source.

For details of how to create such a keystore file, see Section 2.5.3, “Use the CA to Create Signed Certificates in a Java Keystore”.

The sec:trustManagers element is used to specify a list of trusted CA certificates (the server uses this list to decide whether or not to trust certificates presented by clients).

The file attribute of the sec:keyStore element specifies a Java keystore file, truststore.jks, containing one or more trusted CA certificates. The password attribute specifies the password required to access the keystore, truststore.jks. See Section 3.2.2, “Specifying Trusted CA Certificates for HTTPS”.

Note

Instead of the file attribute, you can specify the location of the keystore using either the resource attribute or the url attribute.

The sec:cipherSuitesFilter element can be used to narrow the choice of cipher suites that the server is willing to use for a TLS connection. See Chapter 4, Configuring HTTPS Cipher Suites for details.

The sec:clientAuthentication element determines the server’s disposition towards the presentation of client certificates. The element has the following attributes:

  • want attribute—If true (the default), the server requests the client to present an X.509 certificate during the TLS handshake; if false, the server does not request the client to present an X.509 certificate.
  • required attribute—If true, the server raises an exception if a client fails to present an X.509 certificate during the TLS handshake; if false (the default), the server does not raise an exception if the client fails to present an X.509 certificate.