HttpClient:主机名不匹配 - 可从浏览器访问,但不能从代码访问 [英] HttpClient : hostname didn't match - accessible from browser but not from code
问题描述
我正在尝试使用 HttpClient 从我的代码访问网站:
I am trying to access a website from my code using HttpClient :
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("https://www.datamed.org/search.php?query=gene&searchtype=data");
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httpget, responseHandler);
这是我得到的错误:
Exception in thread "main" javax.net.ssl.SSLException: hostname in certificate didn't match: <www.datamed.org> != <ucrexdc.ucsd.edu> OR <ucrexdc.ucsd.edu>
我从浏览器检查了证书,它似乎是正确的,名称正确.不确定它从哪里获取 ucrexdc.ucsd.edu
.
I checked the certificate from browser, it seems correct, with correct names.
Not sure from where it is picking up ucrexdc.ucsd.edu
.
如果我使用代理,代码确实有效.在 StackOverflow 上经历了很多类似的问题,但在大多数情况下,服务器在用户的控制之下.就我而言,这是一个已经存在的网站.我只有这个网站有这个问题.
The code does work if I use a proxy. Gone through a lot of similar issues on StackOverflow, but in most cases the server was under user's control. In my case, this is an already existing website. and i have this problem only for this website.
会不会是我的环境有问题?
Can it be a problem with my environment?
更新:
我发现这两个网站(datamed.org
和 ucrexdc.ucsd.edu
)具有相同的 IP,169.228.51.21
.会不会有问题,为什么浏览器没有这个问题?
I found out that both the websites (datamed.org
and ucrexdc.ucsd.edu
) have the same IP , 169.228.51.21
. Can it be a problem, why doesn't the browser have issues with this?
更新 2:
我使用的是 apache http-client 4.3.1
,
当我更新到 4.4.1
时,它得到了解决.该问题很可能与 SNI 相关.
I was using apache http-client 4.3.1
,
When i updated to 4.4.1
, it was resolved. the issue was most possibly related to SNI.
推荐答案
HttpClient 提供了两种 Hostname 验证的实现.
HttpClient provides two implementations for Hostname verification.
- 默认主机名验证器
- NoopHostnameVerifier
默认情况下 HttpClient 使用 DefaultHostnameVerifier 实现.您可以尝试不同的主机名验证器实现.
by default HttpClient uses DefaultHostnameVerifier implementation. You can try the different hostname verifier implementation.
SSLContext sslContext = SSLContexts.createSystemDefault();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
HttpClient httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslsf).build();
这篇关于HttpClient:主机名不匹配 - 可从浏览器访问,但不能从代码访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!