带有自签名 SSL 证书的 Apache camel http4

Apache camel http4 with self signed SSL certificate

我真的无法为与主机名不匹配的自签名服务器证书配置 Apache camel https4。

[Do. 2020 16 Juli 13:13:19] [DEBUG] org.apache.camel.processor.Pipeline () - Message exchange has failed: so breaking out of pipeline for exchange: Exchange[ID-lvm-cdbservice-01ct-1594888044674-0-15551] Exception: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

这就是我创建自定义 HttpClientConfigurer 的原因,如 apache camel http 配置中所述。但是这个配置器似乎没有用于我的路由?!有人知道为什么吗?

在某些时候使用了 configureHttpClient 方法

[Do. 2020 16 Juli 10:27:25] [INFO ] com.test.SelfSignedHttpClientConfigurer () - Using SelfSignedHttpClientConfigurer...
[Do. 2020 16 Juli 10:27:25] [INFO ] com.test.SelfSignedHttpClientConfigurer () - ... HttpClient configured!

但是协议没有改变。这就是为什么我猜它没有用于我的路线。

available protocols [[TLSv1.3, TLSv1.2, TLSv1.1, TLSv1]],
currently enabled protocols [[TLSv1.3, TLSv1.2, TLSv1.1, TLSv1]],
and default protocol patterns [Patterns [includes=[.*], excludes=[SSL.*]]].
Resulting enabled protocols are [[TLSv1.3, TLSv1.2, TLSv1.1, TLSv1]].

pom.xml

<properties>
    <camel.version>2.24.3</camel.version>
</properties>

<dependencies>
    <!-- camel -->
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-core</artifactId>
        <version>${camel.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-spring</artifactId>
        <version>${camel.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-http4</artifactId>
        <version>${camel.version}</version>
    </dependency>
</dependencies>

applicationContext.xml

<!-- Apache Camel -->
<camelContext
    xmlns="http://camel.apache.org/schema/spring">
    <!-- HTTP myTime -->
    <route id="myTimeRoute">
        <from uri="file:///tmp/test?consumer.delay=10000" />
        <setHeader headerName="CamelHttpMethod">
            <constant>POST</constant>
        </setHeader>
        <setHeader headerName="Content-Type">
            <constant>application/json</constant>
        </setHeader>
        <to uri="https4://test.de/test?delay=60000&connectTimeout=20000&httpClientConfigurer=#selfSignedHttpClientConfigurer&sslContextParameters=#mySSLContextParameters&throwExceptionOnFailure=false" />
    </route>
</camelContext>

<bean id="selfSignedHttpClientConfigurer"
    class="com.test.SelfSignedHttpClientConfigurer" />

我尝试了有无#(httpClientConfigurer=#selfSignedHttpClientConfigurer 和 httpClientConfigurer=selfSignedHttpClientConfigurer)

SelfSignedHttpClientConfigurer.class

package com.test;

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;

import javax.net.ssl.SSLContext;

import org.apache.camel.component.http4.HttpClientConfigurer;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SelfSignedHttpClientConfigurer implements HttpClientConfigurer {

    /** the logger. */
    private static final Logger LOG = LoggerFactory.getLogger(SelfSignedHttpClientConfigurer.class);

    @Override
    public void configureHttpClient(HttpClientBuilder clientBuilder) {

        try {
            LOG.info("Using SelfSignedHttpClientConfigurer...");

            SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();

            // Allow TLSv1.2 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1.2" },
                null, NoopHostnameVerifier.INSTANCE);

            clientBuilder.setSSLSocketFactory(sslsf);

            LOG.info("... HttpClient configured!");

        } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
            e.printStackTrace();
        }
    }
}

我试过使用 .build() 和不使用。

我终于找到了解决办法。所有教程和文档均已“弃用”,因为 Apache HTTP API 已随版本 4.5 发生变化。您的代码不会出现任何错误,但它根本无法正常工作。

这个post真的帮了我:

SelfSignedHttpClientConfigurer.class

package com.test;

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;

import javax.net.ssl.SSLContext;

import org.apache.camel.component.http4.HttpClientConfigurer;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SelfSignedHttpClientConfigurer implements HttpClientConfigurer {

/** the logger. */
private static final Logger LOG = LoggerFactory.getLogger(SelfSignedHttpClientConfigurer.class);

    @Override
    public void configureHttpClient(HttpClientBuilder clientBuilder) {

        try {
            LOG.info("Using SelfSignedHttpClientConfigurer...");

            final SSLContext sslContext = new SSLContextBuilder()
                .loadTrustMaterial(null, (x509CertChain, authType) -> true).build();

            clientBuilder.setSSLContext(sslContext)
                .setConnectionManager(new PoolingHttpClientConnectionManager(RegistryBuilder
                        .<ConnectionSocketFactory> create().register("http", PlainConnectionSocketFactory.INSTANCE)
                        .register("https",
                                new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE))
                        .build()));

            LOG.info("... HttpClient configured!");

        } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
            e.printStackTrace();
        }

    }

}

applicationContext.xml

<!-- Apache Camel -->
<camelContext
    xmlns="http://camel.apache.org/schema/spring">
    <!-- HTTP myTime -->
    <route id="myTimeRoute">
        <from uri="file:///tmp/test?consumer.delay=10000" />
        <setHeader headerName="CamelHttpMethod">
            <constant>POST</constant>
        </setHeader>
        <setHeader headerName="Content-Type">
            <constant>application/json</constant>
        </setHeader>
        <to uri="https4://test.de/test?httpClientConfigurer=#selfSignedHttpClientConfigurer" />
    </route>
</camelContext>

<bean id="selfSignedHttpClientConfigurer"
    class="com.test.SelfSignedHttpClientConfigurer" />