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.
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:
- Use a commercial third-party to tool to generate and manage your X.509 certificates.
-
Use the free
openssl
utility (which can be downloaded from http://www.openssl.org) and the Javakeystore
utility to generate certificates (see Section 2.5.3, “Use the CA to Create Signed Certificates in a Java Keystore”).
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 thesoap:address
element is configured to use a HTTPS URL. For bindings other than SOAP, you edit the URL appearing in thelocation
attribute of thehttp: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”.
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”.
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.
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>
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”.
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—Iftrue
(the default), the server requests the client to present an X.509 certificate during the TLS handshake; iffalse
, the server does not request the client to present an X.509 certificate. -
required
attribute—Iftrue
, the server raises an exception if a client fails to present an X.509 certificate during the TLS handshake; iffalse
(the default), the server does not raise an exception if the client fails to present an X.509 certificate.