Reputation: 727
We are accessing an external service from our WebSphere Liberty Profile (8.5.5.6) REST service which uses Apache HTTPClient 4.3.5 to connect to the service.
The service just changed to use TLS v1.2, and now our service is failing with: [4/21/16 12:23:37:596 EDT] 0000005d bm.myw3.services.awf.sso.ejb.generator.SSOTokenGeneratorImpl I Exception :: javax.net.ssl.SSLException: Received fatal alert: protocol_version [4/21/16 12:23:37:597 EDT] 0000005d com.ibm.myw3.services.awf.sso.ejb.SSOTokenManagerBean E SSOTokenGeneratorException :: {0} com.ibm.myw3.services.awf.sso.ejb.config.SSOTokenGeneratorException: Exception while executing http request for retrieving Token
We found the following link, and implemented it in our code:
How to set TLS version on apache HttpClient
SSLContext sslContext = SSLContexts.custom().useTLS().build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" }, null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
I have also set the 'https.protocols':
wasadmin 28548 1 10 12:28 pts/0 00:00:55 /usr/lib/jvm/jre-1.7.1-ibm.x86_64/bin/java -javaagent:/opt/IBM/WebSphere/Liberty/wlp/bin/tools/ws-javaagent.jar -Djava.awt.headless=true -XX:MaxPermSize=256m -Dcom.ibm.security.jurisdictionPolicyDir=/devops/w3Services/ssoProxy -Dhttps.protocols=TLSv1.2,TLSv1.1,TLSv1 -jar /opt/IBM/WebSphere/Liberty/wlp/bin/tools/ws-server.jar w3svcs-ssoproxy-svr1
But it is making no difference. Is there something else we need to do in order to get this to work with WLP?
Upvotes: 0
Views: 1577
Reputation: 27603
One cannot set a custom socket factory and a fully initialized connection manager at the same time when building an HttpClient instance. Method #setConnectionManager supersedes #setSSLSocketFactory.
Do either this
SSLContext sslContext = SSLContexts.custom().useProtocol("TLSv1.2").build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" },
new String[] { "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.setSSLSocketFactory(sslsf);
or this
SSLContext sslContext = SSLContexts.custom().useProtocol("TLSv1.2").build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" },
new String[] { "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslsf)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.setConnectionManager(cm);
Oh yes, one more thing. Please consider upgrading to 4.5
Upvotes: 0
Reputation: 727
We've tried some other things, and here is our latest iteration of the code:
SSLContext sslContext = SSLContexts.custom().useProtocol("TLSv1.2").build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" },
new String[] { "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig)
.setConnectionManager(connManager).setSSLSocketFactory(sslsf);
handleAuthentication(uri, httpClientBuilder);
httpClient = httpClientBuilder.build();
I am also setting the following JVM options:
JVM_ARGS=-Dhttps.protocols=TLSv1.2 -Djdk.tls.client.protocols=TLSv1.2 -Djavax.net.debug=all
But we are still getting the error:
[4/21/16 17:27:37:123 EDT] 00000042 id= bm.myw3.services.awf.sso.ejb.generator.SSOTokenGeneratorImpl I Exception :: javax.net.ssl.SSLException: Received fatal alert: protocol_version
[4/21/16 17:27:37:124 EDT] 00000042 id= com.ibm.myw3.services.awf.sso.ejb.SSOTokenManagerBean E SSOTokenGeneratorException :: {0}
com.ibm.myw3.services.awf.sso.ejb.config.SSOTokenGeneratorException: Exception while executing http request for retrieving Token
I have a trace.log from WLP, which I can upload if anyone thinks it would be useful to see. But here aer various entries from the trace:
Default Executor-thread-25, WRITE: TLSv1.2 Handshake, length = 80
Default Executor-thread-25, WRITE: TLSv1.2 Application Data, length = 256
Default Executor-thread-25, READ: TLSv1.2 Application Data, length = 1552
SEND TLSv1.2 ALERT:
Finalizer thread, WRITE: TLSv1.2 Alert, length = 64
And then it goes on to try TLSv1, which the service we're calling doesn't support anymore. I'm not sure what to look for to determine why it's not using TLSv1.2, but nothing is jumping out at me from the trace.
Upvotes: 0