分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

[译]HttpClient请求HTTPS URL

发布时间:2023-09-06 01:44责任编辑:白小东关键词:暂无标签

1.概览

本文将演示如何配置Apache HttpClient 4 添加ssl支持.目的很简单----无需有效证书即可成功请求 HTTPS URLs.

如果你想深入挖掘和学习其他和HttpClient相关的酷知识,请点击httpclient-guide

延伸阅读:

httpclient-connection-management

httpclient-advanced-config

httpclient-4-cookies

2. SSLPeerUnverifiedException异常

使用httpclient若未配置SSL,下面的测试----请求一个HTTPS URL----将会失败:

 1 public class HttpLiveTest { 2 ??3 ????@Test(expected = SSLPeerUnverifiedException.class) 4 ????public void whenHttpsUrlIsConsumed_thenException() ?5 ??????throws ClientProtocolException, IOException { 6 ???7 ????????DefaultHttpClient httpClient = new DefaultHttpClient(); 8 ????????String urlOverHttps 9 ??????????= "https://localhost:8080/spring-security-rest-basic-auth";10 ????????HttpGet getMethod = new HttpGet(urlOverHttps);11 ?????????12 ????????HttpResponse response = httpClient.execute(getMethod);13 ????????assertThat(response.getStatusLine().getStatusCode(), equalTo(200));14 ????}15 }

具体的异常是:

1 javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated2 ????at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:397)3 ????at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:126)4 ????...

不管何时,URL不能建立一个信任的有效链时,都会出现javax.net.ssl.SSLPeerUnverifiedException exception异常.

3.配置SSL--Accept All(HttpClient的版本小于4.3)

下面通过配置HTTP client信任所有链(译者注:chains)无论他们是否有效.

 1 @Test 2 public void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException() ?3 ??throws IOException, GeneralSecurityException { 4 ????TrustStrategy acceptingTrustStrategy = (cert, authType) -> true; 5 ????SSLSocketFactory sf = new SSLSocketFactory( 6 ??????acceptingTrustStrategy, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 7 ????SchemeRegistry registry = new SchemeRegistry(); 8 ????registry.register(new Scheme("https", 8443, sf)); 9 ????ClientConnectionManager ccm = new PoolingClientConnectionManager(registry);10 ?11 ????DefaultHttpClient httpClient = new DefaultHttpClient(ccm);12 ?13 ????String urlOverHttps 14 ??????= "https://localhost:8443/spring-security-rest-basic-auth/api/bars/1";15 ????HttpGet getMethod = new HttpGet(urlOverHttps);16 ?????17 ????HttpResponse response = httpClient.execute(getMethod);18 ????assertThat(response.getStatusLine().getStatusCode(), equalTo(200));19 }

在新的信任策略下,覆盖了原有的标准证书验证过程(原本需要咨询一个配置好的信任管理器)----上面的测试通过则表明现在的client可以请求HTTPS URL了.

4.spring的RestTemplate配置SSL(HttpClient的版本小于4.3)

我们已经知晓如何给原生的HttpClient配置添加SSL支持,再看看一下更高级的client----the Spring RestTemplate.

没有配置SSL的情况下,如预期一致,下面的测试将不会通过:

1 @Test(expected = ResourceAccessException.class)2 public void whenHttpsUrlIsConsumed_thenException() {3 ????String urlOverHttps 4 ??????= "https://localhost:8443/spring-security-rest-basic-auth/api/bars/1";5 ????ResponseEntity<String> response 6 ??????= new RestTemplate().exchange(urlOverHttps, HttpMethod.GET, null, String.class);7 ????assertThat(response.getStatusCode().value(), equalTo(200));8 }

下面配置SSL:

 1 import static org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER; 2 import java.security.GeneralSecurityException; 3 import java.security.cert.X509Certificate; 4 import org.apache.http.auth.AuthScope; 5 import org.apache.http.auth.UsernamePasswordCredentials; 6 import org.apache.http.conn.scheme.Scheme; 7 import org.apache.http.conn.ssl.SSLSocketFactory; 8 import org.apache.http.conn.ssl.TrustStrategy; 9 import org.apache.http.impl.client.DefaultHttpClient;10 import org.springframework.http.HttpMethod;11 import org.springframework.http.ResponseEntity;12 import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;13 import org.springframework.web.client.ResourceAccessException;14 import org.springframework.web.client.RestTemplate;15 ?16 ...17 @Test18 public void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException() 19 ??throws GeneralSecurityException {20 ????HttpComponentsClientHttpRequestFactory requestFactory 21 ??????= new HttpComponentsClientHttpRequestFactory();22 ????DefaultHttpClient httpClient23 ??????= (DefaultHttpClient) requestFactory.getHttpClient();24 ????TrustStrategy acceptingTrustStrategy = (cert, authType) -> true25 ????SSLSocketFactory sf = new SSLSocketFactory(26 ??????acceptingTrustStrategy, ALLOW_ALL_HOSTNAME_VERIFIER);27 ????httpClient.getConnectionManager().getSchemeRegistry()28 ??????.register(new Scheme("https", 8443, sf));29 ?30 ????String urlOverHttps31 ??????= "https://localhost:8443/spring-security-rest-basic-auth/api/bars/1";32 ????ResponseEntity<String> response = new RestTemplate(requestFactory).33 ??????exchange(urlOverHttps, HttpMethod.GET, null, String.class);34 ????assertThat(response.getStatusCode().value(), equalTo(200));35 }

正如你所见,这和原生的HttpClient配置SSL非常相像----我们给 request factory 添加了SSL支持,然后初始化模板时将配置好的factory作为入参.

5.配置SSL(HttpClient版本为4.4)

在4.4版本,不再使用SSLSocketFactory,可简单配置如下:

 1 @Test 2 public void givenIgnoringCertificates_whenHttpsUrlIsConsumed_thenCorrect() 3 ??throws Exception { 4 ????SSLContext sslContext = new SSLContextBuilder() 5 ??????.loadTrustMaterial(null, (certificate, authType) -> true).build(); 6 ??7 ????CloseableHttpClient client = HttpClients.custom() 8 ??????.setSSLContext(sslContext) 9 ??????.setSSLHostnameVerifier(new NoopHostnameVerifier())10 ??????.build();11 ????HttpGet httpGet = new HttpGet(HOST_WITH_SSL);12 ????httpGet.setHeader("Accept", "application/xml");13 ?14 ????HttpResponse response = client.execute(httpGet);15 ????assertThat(response.getStatusLine().getStatusCode(), equalTo(200));16 }

6.Spring RestTemplate 配置 SSL (HttpClient 4.4)

我们可以使用同样的方式配置RestTemplate :

 1 @Test 2 public void givenAcceptingAllCertificatesUsing4_4_whenUsingRestTemplate_thenCorrect() ?3 throws ClientProtocolException, IOException { 4 ????CloseableHttpClient httpClient 5 ??????= HttpClients.custom() 6 ????????.setSSLHostnameVerifier(new NoopHostnameVerifier()) 7 ????????.build(); 8 ????HttpComponentsClientHttpRequestFactory requestFactory ?9 ??????= new HttpComponentsClientHttpRequestFactory();10 ????requestFactory.setHttpClient(httpClient);11 ?12 ????ResponseEntity<String> response 13 ??????= new RestTemplate(requestFactory).exchange(14 ??????urlOverHttps, HttpMethod.GET, null, String.class);15 ????assertThat(response.getStatusCode().value(), equalTo(200));16 }

7.总结

本教程讨论了如何给 Apache HttpClient 配置SSL ,忽略校验以至于能够访问任何 HTTPS URL .并举例说明给Spring RestTemplate配置SSL.

然而需要明白的是:该策略完全忽略证书验证,这可能导致安全漏洞,因此只能用在需要的地方.

本文的示例代码可访问 the GitHub project ,工程基于Eclipse,因此可以轻松导入并运行.

8.原文地址:

传送门

[译]HttpClient请求HTTPS URL

原文地址:https://www.cnblogs.com/wangliangwu/p/8492426.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved