如何使用 Apache HTTPClient 忽略 SSL 证书错误但记录它

How to ignore SSL certificate error using Apache HTTPClient but log it

关于如何使用 Apache HTTPClient 忽略 SSL 证书的示例有很多;我按照 this SO answer 创建了一个客户端。到目前为止,一切都很好。问题是,当证书无效时,客户会盲目接受它,就像我告诉它的那样。却又不想静静的接受;我想记录某种警告,让我知道已接受无效证书。

有什么办法吗?

P.S.:这是用于内部工具,而不是产品代码。我理解并接受忽略证书的风险,所以请不要开始 "holier than thou" 讲座。

装饰传递给SSLContext#init方法的X509TrustManager实例只是一件简单的事情

static class TrustManagerDelegate implements X509TrustManager {

    private final X509TrustManager trustManager;

    TrustManagerDelegate(final X509TrustManager trustManager) {
        super();
        this.trustManager = trustManager;
    }

    @Override
    public void checkClientTrusted(
            final X509Certificate[] chain, final String authType) throws CertificateException {
        trustManager.checkClientTrusted(chain, authType);
    }

    @Override
    public void checkServerTrusted(
            final X509Certificate[] chain, final String authType) {
        try {
            trustManager.checkServerTrusted(chain, authType);
        } catch (CertificateException ex) {
            // Implement proper logging;
            System.out.println(chain[0]);
            ex.printStackTrace(System.out);
        }
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return trustManager.getAcceptedIssuers();
    }

}

...

TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmfactory.init((KeyStore) null);
final TrustManager[] tms = tmfactory.getTrustManagers();
if (tms != null) {
    for (int i = 0; i < tms.length; i++) {
        final TrustManager tm = tms[i];
        if (tm instanceof X509TrustManager) {
            tms[i] = new TrustManagerDelegate((X509TrustManager) tm);
        }
    }
}
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tms, null);

CloseableHttpClient client = HttpClientBuilder.create()
        .setSSLContext(sslContext)
        .build();