2012-11-07 133 views
3

有沒有辦法在請求後使用Apache HttpClient獲取經過身份驗證的服務器的SSL證書 - 僅僅是服務器端的request.getAttribute(「javax.servlet.request.X509Certificate」)的對應部分?Apache HttpClient獲取服務器證書

回答

3

好的,這在某些方面有些偏袒,我希望這樣做的方式可以與任何連接管理器一起工作。我假設你正在運行最新的HttpClient(4.2)

所以,你將不得不做的是添加一個HttpResponseInterceptor到客戶端。

((AbstractHttpClient)client).addResponseInterceptor(new HttpResponseInterceptor() { 
    @Override 
    public void process(HttpResponse response, HttpContext context) throws HttpException, IOException { 
     HttpRoutedConnection routedConnection= (HttpRoutedConnection)context.getAttribute(ExecutionContext.HTTP_CONNECTION); 
     if(routedConnection.isSecure()) { 
      Certificate[] certificates= routedConnection.getSSLSession().getPeerCertificates(); 
      // Assume that PEER_CERTIFICATES is a constant you've defined 
      context.setAttribute(PEER_CERTIFICATES, certificates); 
     } 
    } 
}); 

一旦做到這一點,通過這個客戶端所做的任何請求將檢查是否連接被標記爲「安全」,然後嘗試獲得對等證書。

在這個例子中,我只是放入與對等連接關聯的整個證書數組。

在這一點上,執行你會做類似如下的內容:

HttpContext context= new BasicHttpContext(); 
HttpGet get= new HttpGet(....); 
client.execute(get, context); 
// should contain the array of Certificate - these are more likely X509Certificate instances 
Certificate[] peerCertificates= (Certificate[])context.getAttribute(PEER_CERTIFICATES);certificates 
// do whatever logic to complete and consume the request 

希望這會得到你所需要的 - 如果任何人有超越這一點,他們會理解的建議。

編輯這也可以作爲HttpRequestInterceptor完成,並且具有與連接已建立相同的效果。

+0

太好了,謝謝。 – mtraut

1

對於HttpClient的4.5解決方案需要這樣的改變:

clientBuilder.addInterceptorLast(new HttpResponseInterceptor() { 
     @Override 
     public void process(HttpResponse response, HttpContext context) throws HttpException, IOException { 
      ManagedHttpClientConnection routedConnection = (ManagedHttpClientConnection) context.getAttribute(HttpCoreContext.HTTP_CONNECTION); 
      SSLSession sslSession = routedConnection.getSSLSession(); 
      if (sslSession != null) { 
       Certificate[] certificates = sslSession.getPeerCertificates(); 
       // Assume that PEER_CERTIFICATES is a constant you've defined 
       context.setAttribute(PEER_CERTIFICATES, certificates); 
      } 
     } 
    });