首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >忽略AsyncClientHttp2Multiplexing中的自签名证书

忽略AsyncClientHttp2Multiplexing中的自签名证书
EN

Stack Overflow用户
提问于 2018-02-15 10:01:13
回答 1查看 1K关注 0票数 1

我正在尝试使用单个客户端端点创建多个异步HTTP连接,我已经尝试了Apache站点中给出的多路复用示例

代码片段如下所示,

代码语言:javascript
复制
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);

此示例适用于具有有效证书的站点,但如果要尝试证书已过期/自签名的站点,则会引发下列异常

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)在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(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)sun.security.ssl.Alerts.getSSLException(Alerts.java:192),sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1728),sun.security.ssl.Handshaker.fatalSE(Handshaker.java:304),sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296),sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514),sun.security.ssl。ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026) at sun.security.ssl.Handshaker$1.run(Handshaker.java:966) at sun.security.ssl.Handshaker$1.run(Handshaker.java:963) at java.security.AccessController.doPrivileged(Native Method) sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1416) at org.apache.hc.core5.reactor.ssl。org.apache.hc.core5.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:331)上的SSLIOSession.doRunTask(SSLIOSession.java:274) .8多个原因是: sun.security.validator.ValidatorException: PKIX路径构建失败: sun.security.provider.certpath.SunCertPathBuilderException:无法在sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:的sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)找到有效的认证路径。在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次是由: sun.security.provider.certpath引起的sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141):无法找到有效的认证路径到请求的目标在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

我尝试过的:我创建了一个套接字工厂,它信任connectionManager中的所有证书并尝试设置,但是它创建了一个CloseableHttpClient,我认为它不能用于异步复用,代码如下所示

代码语言:javascript
复制
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中是否有任何方法或方法可以忽略自签名证书。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-15 11:12:25

首先,配置SSL上下文以供应用程序使用。如果你必须这样做的话,让它只信任特定的自签名证书是非常明智的,而不是不加区别地信任所有的证书。

代码语言:javascript
复制
final SSLContext sslContext = SSLContexts.custom()
        .loadTrustMaterial(new TrustAllStrategy())
        .build();

使用给定的SSL上下文创建自定义连接管理器

代码语言:javascript
复制
final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
        .setTlsStrategy(new H2TlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE))
        .build();

使用给定的连接管理器创建自定义HttpAsyncClient实例

代码语言:javascript
复制
final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(
       HttpVersionPolicy.FORCE_HTTP_2, 
       H2Config.DEFAULT, 
       null, 
       ioReactorConfig, 
       connectionManager);

或者,如果您只关心HTTP/2,并且不需要具有HTTP/1.1回落的客户端,请考虑使用HTTP/2优化实现。最小的实现将提供基本的消息传输功能(没有状态管理、没有身份验证、没有缓存、没有自动重定向),并且开销最小。

代码语言:javascript
复制
final MinimalHttp2AsyncClient h2ClientMinimal = HttpAsyncClients.createHttp2Minimal(
      H2Config.DEFAULT, 
      ioReactorConfig, 
      new H2TlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE));

一个功能齐全的实现将提供一个功能齐全的HTTP/2传输,并提供经典HttpClient支持的所有功能,唯一的例外是透明内容解压缩:

代码语言:javascript
复制
final HttpAsyncClient h2Client = HttpAsyncClients.customHttp2()
        .setIOReactorConfig(ioReactorConfig)
        .setTlsStrategy(new H2TlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE))
        .build();

希望这能有所帮助

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48804402

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档