How to use SSL with Jersey 2.x and Apache Connection manager

2.5k views Asked by At

I would like to use connection pooling with my Jersey 2.x rest clients. I have the following code:

ClientConfig clientConfig = new ClientConfig();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(100);
connectionManager.setDefaultMaxPerRoute(20);
clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager);

clientConfig.connectorProvider(new ApacheConnectorProvider());  

Client client = ClientBuilder.newBuilder()
    .withConfig(clientConfig)
    .sslContext(SslConfigurator.getDefaultContext())
    .build();

But this does not work for sites that require a client certificate. If I don't use the PoolingHttpClientConnectionManager (i.e. comment it out like this:)

//clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager);

Then the client certificate is sent.

How can I setup the PoolingHttpClientConnectionManager to use javax.net.ssl... properties?

2

There are 2 answers

1
ok2c On BEST ANSWER

Use SSL socket factory configured with system properties

Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
        .register("http", PlainConnectionSocketFactory.getSocketFactory())
        .register("https", SSLConnectionSocketFactory.getSystemSocketFactory())
        .build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
0
Yves Bossu On

The example above works if you use the default SSL context. If you have a custom SSL context, such as :

    SslConfigurator sslConfig = SslConfigurator.newInstance()
    .trustStoreFile(...).trustStorePassword(...)
    .keyStoreFile(...).keyStorePassword(...).keyPassword(...);
SSLContext sslContext = sslConfig.createSSLContext();

then give it to the PoolingHttpClientConnectionManager as such :

    Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
    .register("http", PlainConnectionSocketFactory.getSocketFactory())
    .register("https", new SSLConnectionSocketFactory(sslContext))
    .build();
    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);

The call to ClientBuilder.sslContext() is no longer necessary.