Using a custom SSLSocketFactory with Apache CXF

Java allows to use a custom VM-wide SSLSocketFactory implementation like so: HttpsURLConnection.setDefaultSSLSocketFactory(SSLSocketFactory). Thus, you can either implement your own SSLSocketFactory or you can configure a regular instance according to your needs/environment. You have to understand that there are probably very few use cases where this method actually really helps. Setting a static default SSLSocketFactory influences all components that require a SSL connection of some sort. The same socket factory instance will be used!

Apache CXF has long had very good SSL support built right in. The documentation is pretty clear about how configure the SSL connection(s). Up to version 2.2.7, however, CXF ignored any custom SSLSocketFactory set as described above. CXF’s HttpsURLConnectionFactory.decorateWithTLS(HttpURLConnection) simply wasn’t prepared for that.

CXF 2.2.7 now supports this through a simple configuration parameter. The feature proposal in the CXF JIRA describes the change: https://issues.apache.org/jira/browse/CXF-2693. I only had to add a few lines to the Spring application context:

  <http-conf:conduit name="*.http-conduit">
    <http-conf:tlsClientParameters useHttpsURLConnectionDefaultSslSocketFactory="true" />
  </http-conf:conduit>
  <!--
    Due to a XML parsing issue mentioned here http://www.mail-archive.com/users@cxf.apache.org/msg13711.html it's
    necessary to import the CXF XMLs explicitly.
  -->
  <import resource="classpath:META-INF/cxf/cxf.xml" />
  <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
  <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

One thought on “Using a custom SSLSocketFactory with Apache CXF

  1. hey, I am having somewhat related issue only. Recently the external SOAP interface which were generating client for changed to https one. and I had an old code base at hand which was generating the java files through cxf and unsecured, http:// based wdl. I chnaged the uri and on maven side everything works fine even the test pass. but when i use this jar in the main project of mine I get this:

    Caused by: java.lang.NoSuchMethodError: javax.net.ssl.HttpsURLConnection.getSSLSocketFactory()Ljavax/net/ssl/SSLSocketFactory;
    at sun.net.www.protocol.https.DelegateHttpsURLConnection.getSSLSocketFactory(DelegateHttpsURLConnection.java:50)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:172)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:801)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:158)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1049)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
    at java.net.URL.openStream(URL.java:1010)
    at org.apache.cxf.resource.URIResolver.tryFileSystem(URIResolver.java:169)
    at org.apache.cxf.resource.URIResolver.resolve(URIResolver.java:119)
    at org.apache.cxf.resource.ExtendedURIResolver.resolve(ExtendedURIResolver.java:41)
    at org.apache.cxf.transport.TransportURIResolver.resolve(TransportURIResolver.java:134)
    at org.apache.cxf.catalog.CatalogWSDLLocator.getBaseInputSource(CatalogWSDLLocator.java:72)
    at org.apache.cxf.wsdl11.AbstractWrapperWSDLLocator.getBaseInputSource(AbstractWrapperWSDLLocator.java:57)
    at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:214)
    at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:179)
    at org.apache.cxf.wsdl11.WSDLServiceFactory.(WSDLServiceFactory.java:91)
    at org.apache.cxf.jaxws.ServiceImpl.initializePorts(ServiceImpl.java:207)
    at org.apache.cxf.jaxws.ServiceImpl.(ServiceImpl.java:150)
    at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:63)
    at javax.xml.ws.Service.(Service.java:56)
    at generated.webservices.com.gbm.sso.ssoclient.AuthenticationServiceInternal.(AuthenticationServiceInternal.java:49)
    at com.gbm.caprice.sso.client.CachingSSOClient.init(CachingSSOClient.java:42)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1536)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1409)
    … 45 more

    Can you please help

Leave a Reply