背景
在某些特殊的项目中虽然使用了HTTPS,但其证书管理又不是采用常规模式,如服务端用了个自签名的证书。
很多组织的内部项目因为各种原因采用了这种方式。(先不深挖这种模式的利弊)
这种情况下,大多数HTTP客户端工具或框架都默认禁止此类证书。
为了让客户端忽略SSL证书校验,需要额外的客户端代码设置。
实现方式
本文针对两种Java常见HTTP客户端请求方式,提供实现样例。
HttpClient(org.apache.http.client)
简单直接的方式
Java代码
-
SSLContext sslContext = SSLContextBuilder.create()
-
.loadTrustMaterial((chain, authType) -> true)
-
.build();
-
-
HttpClient httpClient = HttpClients.custom()
-
.setSSLContext(sslContext)
-
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
-
.build();
复杂的方式——更多自定义配置
HttpClient只是个Interface,这里可自定义的内容非常多。
如,我们可以通过工具类 HttpClientBuilder 来设置各种细节,最终构建出一个 HttpClient。
此处仅提供一些简单的示例。真实项目中需具体问题具体分析,设置合适的策略。
Java代码
-
SSLContext sslContext = new SSLContextBuilder()
-
.loadTrustMaterial(null, (chain, authType) -> true)
-
.build();
-
-
SSLConnectionSocketFactory sslConnectionSocketFactory =
-
new SSLConnectionSocketFactory(
-
sslContext,
-
// 添加你想支持的协议
-
new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"},
-
null,
-
NoopHostnameVerifier.INSTANCE);
-
// 或其它重载方法,如:
-
// new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE)
-
-
Registry socketFactoryRegistry =
-
RegistryBuilder.create()
-
.register("http", PlainConnectionSocketFactory.INSTANCE)
-
.register("https", sslConnectionSocketFactory)
-
.build();
-
-
PoolingHttpClientConnectionManager connectionManager =
-
new PoolingHttpClientConnectionManager(socketFactoryRegistry);
-
-
HttpClient httpClient = HttpClients.custom()
-
.setConnectionManager(connectionManager)
-
.build();
RestTemplate(org.springframework.web.client)
步骤1:参照前文所述的HttpClient,创建一个HttpClient实例
步骤2:创建RestTemplate实例
Java代码
-
// httpClient 是步骤1中创建的
-
HttpComponentsClientHttpRequestFactory requestFactory =
-
new HttpComponentsClientHttpRequestFactory(httpClient);
-
-
RestTemplate restTemplate = new RestTemplate(requestFactory);