内容简介:本文将展示如何使用“全部接受”SSL支持配置Apache HttpClient 4。目标很简单 - 使用没有有效证书的HTTPS URL。如果不使用HttpClient配置SSL ,以下测试(使用HTTPS URL)将失败:异常报错为:
本文将展示如何使用“全部接受”SSL支持配置Apache HttpClient 4。目标很简单 - 使用没有有效证书的HTTPS URL。
SSLPeerUnverifiedException
如果不使用HttpClient配置SSL ,以下测试(使用HTTPS URL)将失败:
public class RestClientLiveManualTest {
@Test(expected = SSLPeerUnverifiedException.class)
public void test()
throws ClientProtocolException, IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
String urlOverHttps
="https://localhost:8082/httpclient-simple)";
HttpGet getMethod = new HttpGet(urlOverHttps);
HttpResponse response = httpClient.execute(getMethod);
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}
}
复制代码
异常报错为:
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:397)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:126)
...
复制代码
该 javax.net.ssl.SSLPeerUnverifiedException
,该报错产生原因,当无法有效为URL建立信任链的时候。
配置通用的SSL(HttpClient <4.3)
现在让我们将HTTPClient配置为信任所有证书,无论其有效性如何:
@Test
public final void test()
throws GeneralSecurityException {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
CloseableHttpClient httpClient = (CloseableHttpClient) requestFactory.getHttpClient();
TrustStrategy acceptingTrustStrategy = (cert, authType) -> true;
SSLSocketFactory sf = new SSLSocketFactory(acceptingTrustStrategy, ALLOW_ALL_HOSTNAME_VERIFIER);
httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 8443, sf));
ResponseEntity<String> response = new RestTemplate(requestFactory).
exchange(urlOverHttps, HttpMethod.GET, null, String.class);
assertThat(response.getStatusCode().value(), equalTo(200));
}
复制代码
随着acceptingTrustStrategy 配置了 true
的测试通过,client能够消费的HTTPS URL。
配置通用的SSL(HttpClient 4.4及更高版本)
使用新的HTTPClient,现在我们有了一个增强的,重新设计的默认SSL主机名验证程序。此外,通过引入SSLConnectionSocketFactory和RegistryBuilder,可以轻松构建SSLSocketFactory。所以我们可以编写上面的测试用例,如:
@Test
public final void test()
throws GeneralSecurityException {
TrustStrategy acceptingTrustStrategy = (cert, authType) -> true;
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,
NoopHostnameVerifier.INSTANCE);
Registry<ConnectionSocketFactory> socketFactoryRegistry =
RegistryBuilder.<ConnectionSocketFactory> create()
.register("https", sslsf)
.register("http", new PlainConnectionSocketFactory())
.build();
BasicHttpClientConnectionManager connectionManager =
new BasicHttpClientConnectionManager(socketFactoryRegistry);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
.setConnectionManager(connectionManager).build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory(httpClient);
ResponseEntity<String> response = new RestTemplate(requestFactory)
.exchange(urlOverHttps, HttpMethod.GET, null, String.class);
assertThat(response.getStatusCode().value(), equalTo(200));
}
复制代码
使用SSL 的Spring RestTemplate(HttpClient <4.3)
现在我们已经了解了如何配置具有SSL支持的原始HttpClient,让我们来看看更高级别的方式-Spring RestTemplate。
如果未配置SSL,则以下测试将按预期会抛异常:
@Test(expected = ResourceAccessException.class)
public void test() {
String urlOverHttps
= "https://localhost:8443/httpclient-simple/api/bars/1";
ResponseEntity<String> response
= new RestTemplate().exchange(urlOverHttps, HttpMethod.GET, null, String.class);
assertThat(response.getStatusCode().value(), equalTo(200));
}
复制代码
那么让我们配置SSL:
@Test
public void test()
throws GeneralSecurityException {
HttpComponentsClientHttpRequestFactory requestFactory
= new HttpComponentsClientHttpRequestFactory();
DefaultHttpClient httpClient
= (DefaultHttpClient) requestFactory.getHttpClient();
TrustStrategy acceptingTrustStrategy = (cert, authType) -> true
SSLSocketFactory sf = new SSLSocketFactory(
acceptingTrustStrategy, ALLOW_ALL_HOSTNAME_VERIFIER);
httpClient.getConnectionManager().getSchemeRegistry()
.register(new Scheme("https", 8443, sf));
String urlOverHttps ="https://localhost:8443/httpclient-simple/api/bars/1";
ResponseEntity<String> response = new RestTemplate(requestFactory).
exchange(urlOverHttps, HttpMethod.GET, null, String.class);
assertThat(response.getStatusCode().value(), equalTo(200));
}
复制代码
这与我们为原始HttpClient配置SSL的方式非常相似 - 我们使用SSL支持配置请求工厂,然后我们实例化通过此预配置工厂的模板。
带有SSL 的Spring RestTemplate(HttpClient 4.4)
我们可以使用相同的方式配置我们的RestTemplate:
@Test
public void test()
throws ClientProtocolException, IOException {
CloseableHttpClient httpClient
= HttpClients.custom()
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
HttpComponentsClientHttpRequestFactory requestFactory
= new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
ResponseEntity<String> response
= new RestTemplate(requestFactory).exchange(
urlOverHttps, HttpMethod.GET, null, String.class);
assertThat(response.getStatusCode().value(), equalTo(200));
}
复制代码
总结
本教程讨论了如何为Apache HttpClient配置SSL,以便它能够使用任何HTTPS URL,而不管证书是什么。还说明了Spring RestTemplate的相同配置。
然而,一个重要的事情是,这种策略完全忽略了证书检查 - 这使得它不安全,只能在有意义的地方使用。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Python for Data Analysis
Wes McKinney / O'Reilly Media / 2012-11-1 / USD 39.99
Finding great data analysts is difficult. Despite the explosive growth of data in industries ranging from manufacturing and retail to high technology, finance, and healthcare, learning and accessing d......一起来看看 《Python for Data Analysis》 这本书的介绍吧!