大气的企业网站设计,企业网站无线端怎么做,毕业设计可以做网站不,公司建网站多少本文将展示如何配置Apache HttpClient 4和5以支持“接受所有”SSL。
目标很简单——访问没有有效证书的HTTPS URL。
SSLPeerUnverifiedException
在未配置SSL的情况下#xff0c;尝试消费一个HTTPS URL时会遇到以下测试失败#xff1a;
Test
void whenHttpsUrlIsConsumed…本文将展示如何配置Apache HttpClient 4和5以支持“接受所有”SSL。
目标很简单——访问没有有效证书的HTTPS URL。
SSLPeerUnverifiedException
在未配置SSL的情况下尝试消费一个HTTPS URL时会遇到以下测试失败
Test
void whenHttpsUrlIsConsumed_thenException() {String urlOverHttps https://localhost:8082/httpclient-simple;HttpGet getMethod new HttpGet(urlOverHttps);assertThrows(SSLPeerUnverifiedException.class, () - {CloseableHttpClient httpClient HttpClients.createDefault();HttpResponse response httpClient.execute(getMethod, new CustomHttpClientResponseHandler());assertThat(response.getCode(), equalTo(200));});
}具体的失败信息是
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticatedat sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:397)at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:126)...当无法为URL建立有效的信任链时就会抛出javax.net.ssl.SSLPeerUnverifiedException异常。
配置SSL - 接受所有HttpClient 5
现在让我们配置HTTP客户端以信任所有证书链无论其有效性如何
Test
void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenOk() throws GeneralSecurityException, IOException {final HttpGet getMethod new HttpGet(HOST_WITH_SSL);final TrustStrategy acceptingTrustStrategy (cert, authType) - true;final SSLContext sslContext SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();final SSLConnectionSocketFactory sslsf new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);final RegistryConnectionSocketFactory socketFactoryRegistry RegistryBuilder.ConnectionSocketFactory create().register(https, sslsf).register(http, new PlainConnectionSocketFactory()).build();final BasicHttpClientConnectionManager connectionManager new BasicHttpClientConnectionManager(socketFactoryRegistry);try (CloseableHttpClient httpClient HttpClients.custom().setConnectionManager(connectionManager).build();CloseableHttpResponse response (CloseableHttpResponse) httpClient.execute(getMethod, new CustomHttpClientResponseHandler())) {final int statusCode response.getCode();assertThat(statusCode, equalTo(HttpStatus.SC_OK));}
}通过新的TrustStrategy覆盖标准证书验证过程后测试现在可以通过客户端能够成功消费HTTPS URL。
配置SSL - 接受所有HttpClient 4.5
对于HttpClient 4.5版本配置方式类似但使用了一些不同的API
Test
public final void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenOk()throws GeneralSecurityException {TrustStrategy acceptingTrustStrategy (cert, authType) - true;SSLContext sslContext SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();SSLConnectionSocketFactory sslsf new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);RegistryConnectionSocketFactory 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);ResponseEntityString response new RestTemplate(requestFactory).exchange(urlOverHttps, HttpMethod.GET, null, String.class);assertThat(response.getStatusCode().value(), equalTo(200));
}Spring RestTemplate与SSLHttpClient 5
了解了如何配置带有SSL支持的基本HttpClient之后我们来看看更高级别的客户端——Spring RestTemplate。
在没有配置SSL的情况下预期的测试会失败
Test
void whenHttpsUrlIsConsumed_thenException() {final String urlOverHttps https://localhost:8443/httpclient-simple/api/bars/1;assertThrows(ResourceAccessException.class, () - {final ResponseEntityString response new RestTemplate().exchange(urlOverHttps, HttpMethod.GET, null, String.class);assertThat(response.getStatusCode().value(), equalTo(200));});
}接下来配置SSL来解决这个问题
Test
void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenOk() throws GeneralSecurityException {final TrustStrategy acceptingTrustStrategy (cert, authType) - true;final SSLContext sslContext SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();final SSLConnectionSocketFactory sslsf new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);final RegistryConnectionSocketFactory socketFactoryRegistry RegistryBuilder.ConnectionSocketFactory create().register(https, sslsf).register(http, new PlainConnectionSocketFactory()).build();final BasicHttpClientConnectionManager connectionManager new BasicHttpClientConnectionManager(socketFactoryRegistry);final CloseableHttpClient httpClient HttpClients.custom().setConnectionManager(connectionManager).build();final HttpComponentsClientHttpRequestFactory requestFactory new HttpComponentsClientHttpRequestFactory(httpClient);final ResponseEntityString response new RestTemplate(requestFactory).exchange(urlOverHttps, HttpMethod.GET, null, String.class);assertThat(response.getStatusCode().value(), equalTo(200));
}这里配置方式与直接使用HttpClient非常相似我们用带有SSL支持的请求工厂配置了RestTemplate。
结论
本教程讨论了如何配置Apache HttpClient以使其能够消费任何HTTPS URL无论证书的有效性如何。
同样也展示了如何对Spring RestTemplate进行同样的配置。
重要的是要理解这种策略完全忽略了证书检查——这使得它不安全仅应在合理的情况下使用。