Apache HttpClient get server certificate

大兔子大兔子 提交于 2019-12-10 16:29:35

问题


Is there a way to get the SSL certificate of the authenticated server using Apache HttpClient after the request - just the counterpart to request.getAttribute("javax.servlet.request.X509Certificate") on the server side?


回答1:


Ok this is a bit meta in some respects and I'm hopefully doing this in a fashion that will work with any connection manager. I'm assuming you're running on the latest HttpClient (4.2)

So, what you will have to do is add an HttpResponseInterceptor to the client.

((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);
        }
    }
});

Once that is done, any request made through this client will check to see if the connection is marked as 'secure' and then attempt to get the peer certificates.

In this example, I'm just putting in the entire array of certificates that were associated with the peer connection.

At this point, to execute you will do something similar to the following:

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

Hopefully that will get what you need - if anyone has suggestions beyond this they'd be appreciated.

EDIT This can also be done as a HttpRequestInterceptor and have the same effect as the connection is already established.




回答2:


For HttpClient 4.5 the solution needs to be changed like this:

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);
            }
        }
    });


来源:https://stackoverflow.com/questions/13273305/apache-httpclient-get-server-certificate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!