简体   繁体   English

Apache HttpClient获取服务器证书

[英]Apache HttpClient get server certificate

有没有一种方法可以在请求后使用Apache HttpClient获取经过身份验证的服务器的SSL证书-只是服务器端与request.getAttribute(“ javax.servlet.request.X509Certificate”)的对应方?

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) 我假设您正在最新的HttpClient(4.2)上运行

So, what you will have to do is add an HttpResponseInterceptor to the client. 因此,您需要做的是向客户端添加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);
        }
    }
});

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. 编辑这也可以作为HttpRequestInterceptor来完成,并具有与已经建立的连接相同的效果。

For HttpClient 4.5 the solution needs to be changed like this: 对于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);
            }
        }
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM