Apache Camel http4 带有自签名 SSL 证书

Ale*_*ing 5 ssl self-signed apache-camel

我真的很难为与主机名不匹配的自签名服务器证书配置 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
Run Code Online (Sandbox Code Playgroud)

这就是为什么我创建了一个自定义 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!
Run Code Online (Sandbox Code Playgroud)

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

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]].
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

应用程序上下文.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" />
Run Code Online (Sandbox Code Playgroud)

我尝试了使用和不使用 # (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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*ing 7

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

这篇文章确实对我有帮助:https ://stackoverflow.com/a/38509015

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();
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

应用程序上下文.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" />
Run Code Online (Sandbox Code Playgroud)