0

I have a project in which HttpsURLConnection is configed to use a customized TrustManager as following:

SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{new MyTrustManager()}, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

There is a REST API client in this project, it uses Jersey client to send HTTP/HTTPS request:

Client client = ClientBuilder.newClient();

However, the HTTPS connection initiated by this Jerset client does not use the defaultSSLSocketFactory I set in HttpsURLConnection and it fails to connect to untrusted HTTPS url.

I need to explicitly set the SslContext on this client to make it work with my TrustManager.

SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{new MyTrustManager()}, null);
Client client = ClientBuilder.newBuilder().sslContext(sslContext).build();

Is there any way to solve this issue?

Thanks.

Lee
  • 535
  • 5
  • 19
  • Does http://stackoverflow.com/questions/2145431/https-using-jersey-client answer this? – PJ Fanning Jul 22 '16 at 22:02
  • No. That post teaches how to send request to HTTPS URL via Jersey. I know how to do this (as showed in the last snippet). What I don't know is how to make the Jersy client use the SslContext I set in HttpsURLConnection. The reason I want to do this is I don't have permission to edit the REST API client code to set SslContext on Jersey client explicitly. – Lee Jul 22 '16 at 22:15

1 Answers1

1

The solution I eventually found is to set the SSLSocketFactory provider property to a customized SSLSocketFactory. Hope this can help others who have similar issues.

Call this in beginning of the program:

Security.setProperty("ssl.SocketFactory.provider", MySSLSocketFactory.class.getCanonicalName());

Here is how MySSLSocketFactory looks like (it also sets connection timeout):

public class MySSLSocketFactory extends SSLSocketFactory {

    private SSLContext sslContext = SSLContext.getInstance(Const.Ssl.PROTOCOL_SSL);


    public MySSLSocketFactory() throws NoSuchAlgorithmException, KeyManagementException {
        this.sslContext.init(
                null,
                new TrustManager[] { new MyTrustManager(false) },
                new SecureRandom());
    }


    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
            throws IOException {
        socket.connect(new InetSocketAddress(host, port), Const.Ssl.CONNECT_TIMEOUT);
        socket.setSoTimeout(Const.Ssl.DATA_TIMEOUT);
        return this.sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }


    @Override
    public String[] getDefaultCipherSuites() {
        return this.sslContext.getSocketFactory().getDefaultCipherSuites();
    }


    @Override
    public String[] getSupportedCipherSuites() {
        return this.sslContext.getSocketFactory().getSupportedCipherSuites();
    }


    @Override
    public Socket createSocket(String host, int port)
            throws IOException, UnknownHostException {
        return this.createSocket(new Socket(), host, port, true);
    }


    @Override
    public Socket createSocket(InetAddress address, int port)
            throws IOException {
        return this.createSocket(new Socket(), address.getHostAddress(), port, true);
    }


    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
            throws IOException, UnknownHostException {
        return this.createSocket(new Socket(), host, port, true);
    }


    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
            throws IOException {
        return this.createSocket(new Socket(), address.getHostAddress(), port, true);
    }
Lee
  • 535
  • 5
  • 19