Two-way SSL is something that has always been a little tricky to configure and manage. Creating a truststore and keystore and working out which certificates go where confuses things. And by adding a SOAP layer on top and battling with CXF further complicates the task. I recently embarked on this activity for a customer and was shocked to learn how badly documented this was on the web. It seems few people have attempted this so I thought it was my time to contribute a little and create a sample project.
My sample project is here. Key points I learnt were:
- It’s better to develop with CXF system logging switched on so you can see your request / reply SOAP messages. In your camel_context.xml, just set the following:
<!-- The interceptors bean definitions - used for logging SOAP requests. --> <!-- They can be removed, when no logging is needed --> <bean id="abstractLoggingInterceptor" abstract="true"> <property name="prettyLogging" value="true" /> </bean> <bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" parent="abstractLoggingInterceptor" /> <bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" parent="abstractLoggingInterceptor" />
- SOAP UI is your friend. Use the Mock test service to act as a sample SOAP server while you develop.
- I prefer developing “contract first” i.e. using a WSDL contract clearly defining each service request/reply. I used the handy wsdl2java cxf-codegen Maven plugin to generate my objects from the WSDL contract
- Namespaces are confusing in CXF. Rather than set the namespace on the CXF endpoint element, I found it clearer to embed the namespace name into the port / service name properties e.g.
And that’s it. I was able to run the sample project within a local Camel Context, and once I was happy with the result, use the project as a template for developing something more specific for my customer.