Reputation: 21
I'm facing issue while trying to override ciphers/protocols on JAX-RS client. Jersey framework is used here.
Following is the way client is built.
Client client = ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(hostnameVerifier).build();
I have tried following approaches, but couldn't succeed.
Created Custom SSLSocketFactory
, and override ciphers and protocols on createSocket()
method of SSL SocketFactory
class.
Then, HttpsURLConnection.setDefaultSSLSocketFactory(sf)
.
But, its not reflected with this approach.
Tried overriding the sslcontext
with help of SslContextFactory
& SSLParameters
, which also could help.
Could someone help in finding a way to override ciphers/protocols programatically on sslContext
of JAX-RS client?
Upvotes: 2
Views: 1062
Reputation: 847
You can implement an SSLSocketFactory :
public class CustomSSLSocketFactory extends SSLSocketFactory {
private final SSLSocketFactory sslSocketFactory;
public CustomSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
this.sslSocketFactory = sslSocketFactory;
}
@Override
public String[] getDefaultCipherSuites() {
return sslSocketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return sslSocketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket() throws IOException {
return adjustEnabledCipherSuites((SSLSocket) sslSocketFactory.createSocket());
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
return adjustEnabledCipherSuites((SSLSocket) sslSocketFactory.createSocket(socket, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException {
return adjustEnabledCipherSuites((SSLSocket) sslSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
return adjustEnabledCipherSuites((SSLSocket) sslSocketFactory.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return adjustEnabledCipherSuites((SSLSocket) sslSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return adjustEnabledCipherSuites((SSLSocket) sslSocketFactory.createSocket(address, port, localAddress, localPort));
}
private SSLSocket adjustEnabledCipherSuites(SSLSocket sslSocket) {
sslSocket.setEnabledCipherSuites(new String[]{"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"});
return sslSocket;
}
}
Now you need to configure your client to use a custom ConnectionFactory that uses the above SSLSocketFactory :
ClientConfig clientConfig = new ClientConfig()
CustomSSLSocketFactory sslSocketFactory = new CustomSSLSocketFactory(sslContext.getSocketFactory());
HttpUrlConnectorProvider.ConnectionFactory factory = url -> {
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
httpsURLConnection.setSSLSocketFactory(sslSocketFactory);
return httpsURLConnection;
};
clientConfig.connectorProvider(new HttpUrlConnectorProvider().connectionFactory(factory));
...
Client client = ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(hostnameVerifier).withConfig(clientConfig).build();
Upvotes: 2