[译]HttpClient请求HTTPS URL

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 authenticated
2     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 @Test
18 public void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException()
19   throws GeneralSecurityException {
20     HttpComponentsClientHttpRequestFactory requestFactory
21       = new HttpComponentsClientHttpRequestFactory();
22     DefaultHttpClient httpClient
23       = (DefaultHttpClient) requestFactory.getHttpClient();
24     TrustStrategy acceptingTrustStrategy = (cert, authType) -> true
25     SSLSocketFactory sf = new SSLSocketFactory(
26       acceptingTrustStrategy, ALLOW_ALL_HOSTNAME_VERIFIER);
27     httpClient.getConnectionManager().getSchemeRegistry()
28       .register(new Scheme("https", 8443, sf));
29
30     String urlOverHttps
31       = "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.原文地址:

传送门

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

时间: 2024-10-01 07:57:28

[译]HttpClient请求HTTPS URL的相关文章

Android 实现 HttpClient 请求Https

如题,默认下,HttpClient是不能请求Https的,需要自己获取 [java] view plaincopy private static final int SET_CONNECTION_TIMEOUT = 5 * 1000; private static final int SET_SOCKET_TIMEOUT = 20 * 1000; public static HttpClient getNewHttpClient() { try { KeyStore trustStore = K

关于httpclient 请求https (如何绕过证书验证)

第一种方法,适用于httpclient4.X 里边有get和post两种方法供你发送请求使用.导入证书发送请求的在这里就不说了,网上到处都是 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.n

[转]java 关于httpclient 请求https (如何绕过证书验证)

原文:http://www.blogjava.net/hector/archive/2012/10/23/390073.html 第一种方法,适用于httpclient4.X 里边有get和post两种方法供你发送请求使用. 导入证书发送请求的在这里就不说了,网上到处都是 import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamRea

通过 Apache Commons HttpClient 发送 HTTPS 请求

1.通过 HTTPS 发送 POST 请求: 2.HTTPS 安全协议采用 TLSv1.2: 3. 使用代理(Proxy)进行 HTTPS 访问: 4.指定 Content-Type 为:application/x-www-form-urlencoded: 5.HTTPS  请求时加载客户端证书(Client Certificate): 6.忽略服务器端证书链(Server Certificate Chain)的校验(Validate). public static void main(Stri

使用HttpClient发送HTTPS请求以及配置Tomcat支持SSL

这里使用的是HttpComponents-Client-4.1.2 1 package com.jadyer.util; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileNotFoundException; 6 import java.io.IOException; 7 import java.security.KeyManagementException; 8 import java

HTTPClient 发送HTTPS请求

HTTPClient 发送HTTP请求就不多说了, 现在给出发送HTTPS请求, 主要思路是忽略证书验证. /** * * @param url * @param contextType "image/jpeg","application/Json" * @return */ public static byte[] sendHttpsGetUrl(HttpClient httpClient1 ,String url,String contextType) { //

httpClient发送https 请求

做项目要用到httpClient发送https到服务器,要求URL中带参数,并且发送xml格式的报文,第一次做,在这里记录一下,以便以后查询的帮助别人:本文在证书配置正确的前提下执行 客户端代码;     public static void httpsRequest() throws Exception {      System.out.println("this is https");         KeyStore trustStore  = KeyStore.getInst

记录一次解决httpcline请求https报handshake_failure错误

概述 当使用httpclinet发起https请求时报如下错误: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:1

.Net Core 3.0后台使用httpclient请求网络网页和图片_使用Core3.0做一个简单的代理服务器

原文:.Net Core 3.0后台使用httpclient请求网络网页和图片_使用Core3.0做一个简单的代理服务器 目标:使用.net core最新的3.0版本,借助httpclient和本机的host域名代理,实现网络请求转发和内容获取,最终显示到目标客户端! 背景:本人在core领域是个新手,对core的使用不多,因此在实现的过程中遇到了很多坑,在这边博客中,逐一介绍下.下面进入正文 正文: 1-启用httpClient注入: 参考文档:https://docs.microsoft.c