4

有没有办法在请求后使用 Apache HttpClient 获取经过身份验证的服务器的 SSL 证书 - 只是服务器端 request.getAttribute("javax.servlet.request.X509Certificate") 的对应物?

4

2 回答 2

4

好的,这在某些方面有点元,我希望以一种适用于任何连接管理器的方式来做这件事。我假设您在最新的 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 完成,并且与已经建立的连接具有相同的效果。

于 2012-11-07T16:49:01.623 回答
2

对于 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);
            }
        }
    });
于 2016-03-02T14:43:17.807 回答