首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

java 用httpclient访问https时经常返回403的原因

纠结了一天的问题终于落下了帷幕!先听一首歌吧

今天使用了一些httpclient包进行https网页数据的访问,但是一直返回403的问题,一开始以为网站做了限制为了防止爬虫,后来就加入了头部user-Agent来模拟浏览器,结果还是不行。紧接着又加入了cookie,结果仍然返回403。直到下午去github上看到了一个二次封装httpclient的util工具。下载下来放到了idea里访问了一下https的这个url结果成功了。对比了一下不同之处,除了httpclient jar包的版本有高低外还有就是使用的jdk版本不同。于是将相同版本的httpclient jar包放到新建的测试项目下,同样使用jdk1.6 ,结果还是不行。此时就定位到问题的所在了,原来是jdk的版本导致的问题。紧接着在百度搜所了一下原因找到了以下的文章:

问题描述:访问https出现hostname in certificate didn't match问题,本地测试正常原因是本地环境支持了SNI(Server Name Indication),虚拟主机大力发展起来,造成了一个IP会对应多个域名的情况,SNI就是专门用于解决这个问题,它允许客户端在发起SSL握手请求时,就提交请求的Host信息,使得服务器能够切换到正确的域并返回相应的证书。

在java客户端上,SNI要求JDK至少到

,HttpClient至少到4.3.2,本地测试环境满足该要求,而线上环境JDK是1.6的所以会有问题。

解决办法

1,升级运行环境到满足SNI的要求

2,选择忽略hostname校验

可以创建X509HostnameVerifier,重载verify(String hostname, SSLSession session)方法返回true,并设置到httpclient,用于https请求。

新建MyHttpsClient 类

public class MyHttpsClient {

public static MyHttpsClient getInstance(){

return new MyHttpsClient();

}

public CloseableHttpClient createHttpClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException{

SSLContextBuilder builder = SSLContexts.custom();

builder.loadTrustMaterial(null, new TrustStrategy() {

@Override

public boolean isTrusted(X509Certificate[] arg0, String arg1)

throws CertificateException {

// TODO Auto-generated method stub

return true;

}

});

SSLContext sslContext = builder.build();

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(

sslContext, new X509HostnameVerifier() {

@Override

public void verify(String arg0, SSLSocket arg1)

throws IOException {

// TODO Auto-generated method stub

}

@Override

public void verify(String arg0, X509Certificate arg1)

throws SSLException {

// TODO Auto-generated method stub

}

@Override

public void verify(String arg0, String[] arg1, String[] arg2)

throws SSLException {

// TODO Auto-generated method stub

}

@Override

public boolean verify(String hostname, SSLSession session) {

// TODO Auto-generated method stub

return true;

}

});

Registry socketFactoryRegistry = RegistryBuilder

. create().register("https", sslsf)

.build();

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(

socketFactoryRegistry);

CloseableHttpClient httpclient = HttpClients.custom()

.setConnectionManager(cm).build();

return httpclient;

}

}

在HttpUtil中,使用 CloseableHttpClient httpclient = MyHttpsClient.getInstance().createHttpClient();

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20171223G0N1UM00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券