java - 使用 Apache Async HttpClient 4.0.x 时忽略 HTTPS 连接上的错误证书

标签 java apache ssl asynchronous apache-httpclient-4.x

我正在使用 Async Apache HttpClient (CloseableHttpAsyncClient) 连接到服务器,但我遇到了以下异常:

javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:130)
    at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.failed(DefaultClientExchangeHandlerImpl.java:258)
    at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.exception(HttpAsyncRequestExecutor.java:123)
    at org.apache.http.impl.nio.client.InternalIODispatch.onException(InternalIODispatch.java:68)
    at org.apache.http.impl.nio.client.InternalIODispatch.onException(InternalIODispatch.java:37)
    at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:124)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:159)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:338)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:316)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:277)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:105)
    at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:584)
    at java.lang.Thread.run(Thread.java:695)
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Handshaker.java:1015)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:485)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1108)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1080)
    at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:452)
    at org.apache.http.nio.reactor.ssl.SSLIOSession.doWrap(SSLIOSession.java:220)
    at org.apache.http.nio.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:254)
    at org.apache.http.nio.reactor.ssl.SSLIOSession.isAppInputReady(SSLIOSession.java:391)
    at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:119)
    ... 7 more
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1508)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:243)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1209)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:135)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
    at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Handshaker.java:533)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Handshaker.java:952)
    at org.apache.http.nio.reactor.ssl.SSLIOSession.doRunTask(SSLIOSession.java:238)
    at org.apache.http.nio.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:276)
    ... 9 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
    at sun.security.validator.Validator.validate(Validator.java:218)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1188)
    ... 16 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
    ... 22 more

由于这是一个测试服务器,我只想让 CloseableHttpAsyncClient 忽略所有 SSL 错误。我知道如何使用 HttpClient 的非异步版本来执行此操作(例如,这已得到回答 here),但我无法使用异步版本使其工作。

我试过以下方法:

TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
    public boolean isTrusted(X509Certificate[] certificate, String authType) {
        return true;
    }
};

SSLContext sslContext = null;
try {
    sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
} catch (Exception e) {
    // Handle error
}

CloseableHttpAsyncClient client = HttpAsyncClients.custom()
        .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
        .setSSLContext(sslContext).build();

但它不起作用。有谁知道如何解决这个问题?

最佳答案

实际上,我在问题中提供的代码有效。问题是我使用的是 Unirest (它在后台使用 Apache HttpClient)并像这样配置它:

Unirest.setAsyncHttpClient(createHttpAsyncClient(CONNECTION_TIMEOUT, SOCKET_TIMEOUT));
Unirest.setTimeouts(CONNECTION_TIMEOUT, SOCKET_TIMEOUT);

问题是“setTimeouts”在没有任何指示的情况下覆盖了我在 createHttpAsyncClient 中所做的配置。更改为

Unirest.setTimeouts(CONNECTION_TIMEOUT, SOCKET_TIMEOUT);
Unirest.setAsyncHttpClient(createHttpAsyncClient(CONNECTION_TIMEOUT, SOCKET_TIMEOUT));

使一切正常。

因此,如果其他人对普通 Async Apache HTTPClient 有同样的问题,那么使其信任所有证书的代码如下:

TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
    public boolean isTrusted(X509Certificate[] certificate, String authType) {
        return true;
    }
};

SSLContext sslContext = null;
try {
    sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
} catch (Exception e) {
    // Handle error
}

CloseableHttpAsyncClient client = HttpAsyncClients.custom()
        .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
        .setSSLContext(sslContext).build();

关于java - 使用 Apache Async HttpClient 4.0.x 时忽略 HTTPS 连接上的错误证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27959164/

相关文章:

apache - 如何使用 .htaccess 拒绝除一个目录名称以外的所有目录名称?

apache - 是否可以在每个 API Respurce 级别上在 Apache Web 2.4 中启用相互 SSL?

Java - 如果文本文件存在,则创建 append "1"的新文件

java - Android 淡入淡出不工作

apache - lbmethod_heartbeat :notice - No slotmem from mod_heartmonitor --error after installing apache2. 4.2

apache - 在我的情况下如何解决 svn : E195019: Redirect cycle detected,?

ssl - SAML over SSL - SAML token

apache 端口已禁用但仍在工作

java - 如何知道不同数组列表中的两个元素是否发生碰撞?

java - 在 Ant 构建中引用外部库