Tuesday, April 30, 2019

Securing the Apache Camel REST DSL

Recently I put together a simple test-case for Apache Camel's REST DSL and realised that it illustrated quite a few security concepts, as well as various Camel components, that might be interesting to blog about. The test-case is a simple spring-based project, which is available on github here:
  • camel-jetty: A test-case for the Camel Jetty component, TLS, the REST DSL + Jasypt.
In particular, the Camel spring configuration is here. Let's take a look at the different pieces one by one.

1) The Apache Camel REST DSL

Apache Camel offers a REST DSL which makes it really easy to create a simple REST service.
Here we are creating a simple REST service on the "/data" path that produces an XML response when invoked with a GET request. The actual functionality is delegated to a Camel route called "direct:get":

Here we are reading in some files from a directory using the Camel File component and using "pollEnrich" to include the contents of that directory into the message that is returned to the user. Finally we need to tell Camel how to create the REST DSL. Camel supports a wide range of components, but for the purposes of this example we are using the Camel Jetty component:

Note the port is not hard-coded, but instead retrieved from a randomly generated property in the pom using the "reserve-network-port" goal of the "build-helper-maven-plugin".

2) Getting TLS to work with the Camel REST DSL

To support TLS with the Camel REST DSL, we need to set the scheme to "https" as above in the "restConfiguration". The REST configuration also refers to a property called "sslContextParameters", which is where we obtain the keys required to support TLS. See the Camel JSSE documentation for more information on this property.

The sslContextParameters bean definition allows us to define the key managers and trust managers for the TLS endpoint by referring to Java keystore files with the relevant passwords. If we are not supporting client authentication, the trustManagers portion can be omitted.

3) Using Jasypt to decrypt keystore passwords for use in TLS

Note above that we have not hard-coded the TLS keystore passwords in our Camel spring configuration, but are instead retrieving them from a property. Camel offers the ability to store the passwords in encrypted form, by using the Camel Jasypt component to decrypt them given a master password. The encrypted passwords themselves are stored in a passwords.properties file:

These encrypted passwords are obtained using the camel-jasypt jar (shipped for example in the Camel distribution):
  • java -jar camel-jasypt-2.23.1.jar -c encrypt -p master-secret -i storepass
To decrypt the passwords at runtime, we define the following bean in our Camel spring configuration:
This retrieves the master password from a system property. For the purposes of this demo, the password is set as a system property in the "maven-surefire-plugin" defined in the pom.

4) Invoking on our secured REST service using the Camel HTTP4 component

The demo also includes a client route which invokes on the secured REST service we have created. We use the Camel HTTP4 component for this:

We start the route using the Camel Timer component, before calling the HTTP4 component. As we have included a query String in the request URI, the http4 component will issue a GET request. As for the REST service, we need to configure the TLS keys using the "sslContextParameters" parameter.

On the client side we only need the trustManagers configuration, unless of course we want to support client authentication. For the purposes of this demo, we also need to configure a custom x509HostnameVerifier property. This is because the TLS certificate the service is using will not be accepted by the client by default, as the common name of the certificate does not match the domain name of the service. We can circumvent this  (for testing purposes only, it is not secure!) by using the following hostname verifier:

Finally we log the service response to the console so we can see the test-case working.

No comments:

Post a Comment