如何让Jersey客户端使用HttpsURLConnection中设置的defaultSSLSocketFactory?

时间:2016-07-22 21:58:26

标签: java ssl https jersey

我有一个项目,其中HttpsURLConnection被配置为使用自定义的TrustManager如下:

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

此项目中有一个REST API客户端,它使用Jersey客户端发送HTTP / HTTPS请求:

Client client = ClientBuilder.newClient();

但是,此Jerset客户端启动的HTTPS连接不使用我在HttpsURLConnection中设置的defaultSSLSocketFactory,并且无法连接到不受信任的HTTPS URL。

我需要在此客户端上显式设置SslContext以使其与我的TrustManager一起使用。

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

有没有办法解决这个问题?

感谢。

1 个答案:

答案 0 :(得分:1)

我最终找到的解决方案是将SSLSocketFactory提供程序属性设置为自定义的SSLSocketFactory。希望这可以帮助其他有类似问题的人。

在程序开头调用它:

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

以下是MySSLSocketFactory的外观(它还设置了连接超时):

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);
    }