如何让 Jersey 客户端使用 HttpsURLConnection 中设置的 defaultSSLSocketFactory?
Posted
技术标签:
【中文标题】如何让 Jersey 客户端使用 HttpsURLConnection 中设置的 defaultSSLSocketFactory?【英文标题】:How to let Jersey client use the defaultSSLSocketFactory set in HttpsURLConnection? 【发布时间】:2016-11-26 21:51:35 【问题描述】:我有一个项目,其中 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();
有没有办法解决这个问题?
谢谢。
【问题讨论】:
***.com/questions/2145431/https-using-jersey-client 会回答这个问题吗? 没有。那篇文章讲授了如何通过 Jersey 向 HTTPS URL 发送请求。我知道如何做到这一点(如上一个 sn-p 所示)。我不知道的是如何让 Jersy 客户端使用我在 HttpsURLConnection 中设置的 SslContext。我想这样做的原因是我无权编辑 REST API 客户端代码以在 Jersey 客户端上显式设置 SslContext。 【参考方案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);
【讨论】:
以上是关于如何让 Jersey 客户端使用 HttpsURLConnection 中设置的 defaultSSLSocketFactory?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Jersey 客户端中默认使用 Genson 提供程序?
如何让OkHttp从Jersey获取参数并在Interceptor中使用?
如何强制 java SSLContext 使用 TLSv1.1