2016-12-08 44 views
0

我想從我的代碼訪問網站使用的HttpClient: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

如果我使用代理,代碼可以正常工作。 在StackOverflow上經歷了很多類似的問題,但在大多數情況下,服務器都在用戶的控制之下。就我而言,這是一個已經存在的網站。我只有這個網站有這個問題。

它可能是我的環境問題嗎?

UPDATE:

我發現這兩個網站(datamed.orgucrexdc.ucsd.edu)具有相同的IP,169.228.51.21。它可能是一個問題,爲什麼瀏覽器沒有這個問題?

更新2:

我使用Apache http-client 4.3.1
當我更新到4.4.1,它被解決。這個問題最可能與SNI有關。

+0

這可能幫助http://stackoverflow.com/questions/2642777/trusting-all-certificates-using-httpclient-over-https – nullpointer

+0

所看到的,它表明一個解決辦法,這不應當被使用prod代碼。此外,我也想知道是什麼導致這種情況發生 – gaurav5430

+0

@ScaryWombat新來的這個,沒有看到在例子中的任何Keystore代碼。我可以在沒有任何密鑰庫的情況下連接到google.com。另外,datamed.org不在我的服務器上。 – gaurav5430

回答

0

HttpClient爲主機名驗證提供了兩種實現。

  1. DefaultHostnameVerifier
  2. NoopH​​ostnameVerifier

默認的HttpClient使用DefaultHostnameVerifier實施。你可以嘗試不同的主機名驗證器實現。

SSLContext sslContext = SSLContexts.createSystemDefault(); 
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); 
HttpClient httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslsf).build(); 
+0

千萬不要在生產代碼中這樣做。我遇到了太多類似這樣的情況。這是爲了劫持或攻擊而開始的。瞭解TLS如何工作以及如何參與證書不要執行此操作。 –

+0

@DaveG感謝信息戴夫。你知道TLS的很好的文檔嗎? – Ravi

+0

這可能是一個很好的起點https://www.sans.org/reading-room/whitepapers/protocols/ssl-tls-beginners-guide-1029。在這個問題上有很多可用的資源。我會提出一個stackoverflow問題。您可能會被提示其他類似或確切的問題。 –

相關問題