忽略 AsyncClientHttp2Multiplexing 中的自签名证书
Ignore self signed certificates in AsyncClientHttp2Multiplexing
我正在尝试使用单个客户端端点创建多个异步 HTTP 连接我已经尝试了 Apache site
中给出的多路复用示例
代码片段如下,
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
.setSoTimeout(Timeout.ofSeconds(5))
.build();
final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(
HttpVersionPolicy.FORCE_HTTP_2, H2Config.DEFAULT, null, ioReactorConfig);
client.start();
final HttpHost target = new HttpHost("localhost", 7070, "https");
final Future<AsyncClientEndpoint> leaseFuture = client.lease(target, null);
final AsyncClientEndpoint endpoint = leaseFuture.get(30, TimeUnit.SECONDS);
try {
final String[] requestUris = new String[] {"/test.html"};
final CountDownLatch latch = new CountDownLatch(requestUris.length);
for (final String requestUri: requestUris) {
final SimpleHttpRequest request = SimpleHttpRequest.get(target, requestUri);
endpoint.execute(
SimpleRequestProducer.create(request),
SimpleResponseConsumer.create(),
new FutureCallback<SimpleHttpResponse>() {
@Override
public void completed(final SimpleHttpResponse response) {
latch.countDown();
System.out.println(requestUri + "->" + response.getCode());
System.out.println(response.getBody());
}
@Override
public void failed(final Exception ex) {
latch.countDown();
System.out.println(requestUri + "->" + ex);
}
@Override
public void cancelled() {
latch.countDown();
System.out.println(requestUri + " cancelled");
}
});
}
latch.await();
} finally {
endpoint.releaseAndReuse();
}
System.out.println("Shutting down");
client.shutdown(ShutdownType.GRACEFUL);
此示例适用于具有有效证书的网站,但如果我想尝试证书已 expired/self 签名的网站,它会抛出以下异常
javax.net.ssl.SSLHandshakeException: General SSLEngine problem javax.net.ssl.SSLHandshakeException: General SSLEngine problem at
sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1478) at
sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:535)
at
sun.security.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1214)
at sun.security.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1186) at
javax.net.ssl.SSLEngine.wrap(SSLEngine.java:469) at
org.apache.hc.core5.reactor.ssl.SSLIOSession.doWrap(SSLIOSession.java:256)
at
org.apache.hc.core5.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:294)
at
org.apache.hc.core5.reactor.ssl.SSLIOSession.isAppInputReady(SSLIOSession.java:502)
at
org.apache.hc.core5.reactor.InternalDataChannel.onIOEvent(InternalDataChannel.java:112)
at
org.apache.hc.core5.reactor.InternalChannel.handleIOEvent(InternalChannel.java:50)
at
org.apache.hc.core5.reactor.SingleCoreIOReactor.processEvents(SingleCoreIOReactor.java:173)
at
org.apache.hc.core5.reactor.SingleCoreIOReactor.doExecute(SingleCoreIOReactor.java:123)
at
org.apache.hc.core5.reactor.AbstractSingleCoreIOReactor.execute(AbstractSingleCoreIOReactor.java:80)
at
org.apache.hc.core5.reactor.IOReactorWorker.run(IOReactorWorker.java:44)
at java.lang.Thread.run(Thread.java:748) Caused by:
javax.net.ssl.SSLHandshakeException: General SSLEngine problem at
sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at
sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1728) at
sun.security.ssl.Handshaker.fatalSE(Handshaker.java:304) at
sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) at
sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514)
at
sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026) at
sun.security.ssl.Handshaker.run(Handshaker.java:966) at
sun.security.ssl.Handshaker.run(Handshaker.java:963) at
java.security.AccessController.doPrivileged(Native Method) at
sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1416)
at
org.apache.hc.core5.reactor.ssl.SSLIOSession.doRunTask(SSLIOSession.java:274)
at
org.apache.hc.core5.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:331)
... 8 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:397)
at
sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
at sun.security.validator.Validator.validate(Validator.java:260) at
sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
at
sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:281)
at
sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)
at
sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1501)
... 16 more Caused by:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target at
sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at
sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at
sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
... 22 more
我尝试过的:
我创建了一个信任所有证书的套接字工厂并尝试在 connectionManager 中设置但是创建了一个 CloseableHttpClient 并且我认为它不能用于异步多路复用,代码如下
SSLContext sslContext = SSLContextBuilder
.create()
.loadTrustMaterial(new TrustSelfSignedStrategy())
.build();
// we can optionally disable hostname verification.
// if you don't want to further weaken the security, you don't have to include this.
HostnameVerifier allowAllHosts = new NoopHostnameVerifier();
// create an SSL Socket Factory to use the SSLContext with the trust self signed certificate strategy
// and allow all hosts verifier.
SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, allowAllHosts);
Registry<ConnectionSocketFactory> r = RegistryBuilder.<ConnectionSocketFactory>create().register("https", connectionFactory).build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(r);
CloseableHttpClient build = HttpClients.custom().setConnectionManager(cm).build();
如果有任何方法或解决方法可以忽略 MinimalHttpAsyncClient 中的自签名证书,请告诉我。
首先,配置您的应用程序要使用的 SSL 上下文。如果绝对必须这样做,强烈建议让它只信任特定的自签名证书,而不是不加选择地信任所有证书
final SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(new TrustAllStrategy())
.build();
使用给定的 SSL 上下文创建自定义连接管理器
final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
.setTlsStrategy(new H2TlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE))
.build();
使用给定的连接管理器创建自定义 HttpAsyncClient
实例
final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(
HttpVersionPolicy.FORCE_HTTP_2,
H2Config.DEFAULT,
null,
ioReactorConfig,
connectionManager);
或者,如果您只关心 HTTP/2 并且不需要具有 HTTP/1.1 后备功能的客户端,请考虑使用 HTTP/2 优化实现。最小的实现将以尽可能少的开销提供基本的消息传输功能(无状态管理、无身份验证、无缓存、无自动重定向)。
final MinimalHttp2AsyncClient h2ClientMinimal = HttpAsyncClients.createHttp2Minimal(
H2Config.DEFAULT,
ioReactorConfig,
new H2TlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE));
全功能实施将提供全功能 HTTP/2 传输,具有经典 HttpClient
支持的所有功能,唯一例外是透明内容解压缩:
final HttpAsyncClient h2Client = HttpAsyncClients.customHttp2()
.setIOReactorConfig(ioReactorConfig)
.setTlsStrategy(new H2TlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE))
.build();
希望对您有所帮助
我正在尝试使用单个客户端端点创建多个异步 HTTP 连接我已经尝试了 Apache site
中给出的多路复用示例代码片段如下,
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
.setSoTimeout(Timeout.ofSeconds(5))
.build();
final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(
HttpVersionPolicy.FORCE_HTTP_2, H2Config.DEFAULT, null, ioReactorConfig);
client.start();
final HttpHost target = new HttpHost("localhost", 7070, "https");
final Future<AsyncClientEndpoint> leaseFuture = client.lease(target, null);
final AsyncClientEndpoint endpoint = leaseFuture.get(30, TimeUnit.SECONDS);
try {
final String[] requestUris = new String[] {"/test.html"};
final CountDownLatch latch = new CountDownLatch(requestUris.length);
for (final String requestUri: requestUris) {
final SimpleHttpRequest request = SimpleHttpRequest.get(target, requestUri);
endpoint.execute(
SimpleRequestProducer.create(request),
SimpleResponseConsumer.create(),
new FutureCallback<SimpleHttpResponse>() {
@Override
public void completed(final SimpleHttpResponse response) {
latch.countDown();
System.out.println(requestUri + "->" + response.getCode());
System.out.println(response.getBody());
}
@Override
public void failed(final Exception ex) {
latch.countDown();
System.out.println(requestUri + "->" + ex);
}
@Override
public void cancelled() {
latch.countDown();
System.out.println(requestUri + " cancelled");
}
});
}
latch.await();
} finally {
endpoint.releaseAndReuse();
}
System.out.println("Shutting down");
client.shutdown(ShutdownType.GRACEFUL);
此示例适用于具有有效证书的网站,但如果我想尝试证书已 expired/self 签名的网站,它会抛出以下异常
javax.net.ssl.SSLHandshakeException: General SSLEngine problem javax.net.ssl.SSLHandshakeException: General SSLEngine problem at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1478) at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:535) at sun.security.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1214) at sun.security.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1186) at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:469) at org.apache.hc.core5.reactor.ssl.SSLIOSession.doWrap(SSLIOSession.java:256) at org.apache.hc.core5.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:294) at org.apache.hc.core5.reactor.ssl.SSLIOSession.isAppInputReady(SSLIOSession.java:502) at org.apache.hc.core5.reactor.InternalDataChannel.onIOEvent(InternalDataChannel.java:112) at org.apache.hc.core5.reactor.InternalChannel.handleIOEvent(InternalChannel.java:50) at org.apache.hc.core5.reactor.SingleCoreIOReactor.processEvents(SingleCoreIOReactor.java:173) at org.apache.hc.core5.reactor.SingleCoreIOReactor.doExecute(SingleCoreIOReactor.java:123) at org.apache.hc.core5.reactor.AbstractSingleCoreIOReactor.execute(AbstractSingleCoreIOReactor.java:80) at org.apache.hc.core5.reactor.IOReactorWorker.run(IOReactorWorker.java:44) at java.lang.Thread.run(Thread.java:748) Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1728) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:304) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026) at sun.security.ssl.Handshaker.run(Handshaker.java:966) at sun.security.ssl.Handshaker.run(Handshaker.java:963) at java.security.AccessController.doPrivileged(Native Method) at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1416) at org.apache.hc.core5.reactor.ssl.SSLIOSession.doRunTask(SSLIOSession.java:274) at org.apache.hc.core5.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:331) ... 8 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:397) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302) at sun.security.validator.Validator.validate(Validator.java:260) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:281) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1501) ... 16 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392) ... 22 more
我尝试过的: 我创建了一个信任所有证书的套接字工厂并尝试在 connectionManager 中设置但是创建了一个 CloseableHttpClient 并且我认为它不能用于异步多路复用,代码如下
SSLContext sslContext = SSLContextBuilder
.create()
.loadTrustMaterial(new TrustSelfSignedStrategy())
.build();
// we can optionally disable hostname verification.
// if you don't want to further weaken the security, you don't have to include this.
HostnameVerifier allowAllHosts = new NoopHostnameVerifier();
// create an SSL Socket Factory to use the SSLContext with the trust self signed certificate strategy
// and allow all hosts verifier.
SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, allowAllHosts);
Registry<ConnectionSocketFactory> r = RegistryBuilder.<ConnectionSocketFactory>create().register("https", connectionFactory).build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(r);
CloseableHttpClient build = HttpClients.custom().setConnectionManager(cm).build();
如果有任何方法或解决方法可以忽略 MinimalHttpAsyncClient 中的自签名证书,请告诉我。
首先,配置您的应用程序要使用的 SSL 上下文。如果绝对必须这样做,强烈建议让它只信任特定的自签名证书,而不是不加选择地信任所有证书
final SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(new TrustAllStrategy())
.build();
使用给定的 SSL 上下文创建自定义连接管理器
final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
.setTlsStrategy(new H2TlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE))
.build();
使用给定的连接管理器创建自定义 HttpAsyncClient
实例
final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(
HttpVersionPolicy.FORCE_HTTP_2,
H2Config.DEFAULT,
null,
ioReactorConfig,
connectionManager);
或者,如果您只关心 HTTP/2 并且不需要具有 HTTP/1.1 后备功能的客户端,请考虑使用 HTTP/2 优化实现。最小的实现将以尽可能少的开销提供基本的消息传输功能(无状态管理、无身份验证、无缓存、无自动重定向)。
final MinimalHttp2AsyncClient h2ClientMinimal = HttpAsyncClients.createHttp2Minimal(
H2Config.DEFAULT,
ioReactorConfig,
new H2TlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE));
全功能实施将提供全功能 HTTP/2 传输,具有经典 HttpClient
支持的所有功能,唯一例外是透明内容解压缩:
final HttpAsyncClient h2Client = HttpAsyncClients.customHttp2()
.setIOReactorConfig(ioReactorConfig)
.setTlsStrategy(new H2TlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE))
.build();
希望对您有所帮助