首页 > 解决方案 > 在 Spring Boot Apache Camel REST API 中配置 HTTPS,密钥库使用 camel-jetty 组件具有多个证书

问题描述

我正在尝试在我的 apache camel Spring Boot REST 应用程序(使用 apache-camel v3.11.1、springboot v2.5.3)中配置 https,其密钥库具有多个证书。

问题:

Application run failed

org.apache.camel.RuntimeCamelException: java.lang.IllegalStateException: KeyStores with multiple certificates are not supported on the base class org.eclipse.jetty.util.ssl.SslContextFactory. (Use org.eclipse.jetty.util.ssl.SslContextFactory$Server or org.eclipse.jetty.util.ssl.SslContextFactory$Client instead)
    at org.apache.camel.RuntimeCamelException.wrapRuntimeCamelException(RuntimeCamelException.java:51) ~[camel-api-3.11.1.jar:3.11.1]

项目设置:

pom.xml:(仅依赖项,以表明我没有使用spring-boot-web-starter

    ..
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.camel.springboot</groupId>
            <artifactId>camel-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.camel.springboot</groupId>
            <artifactId>camel-jetty-starter</artifactId>
        </dependency>
        ..
        ..<!-- all other required dependencies are in place-->
        ..
    </dependencies>
    ..

应用程序属性

#camel.component.jetty.keystore=keystore-with-one-certificate.jks # WORKS
camel.component.jetty.keystore=keystore-with-multiple-certificates.jks # DOESN'T WORK
camel.component.jetty.ssl-key-password=password
camel.component.jetty.ssl-password=password

休息路线:

        restConfiguration()
        .component("jetty")
        .scheme("https")
        .port("8080");
        
        rest()
        .path("/api")
        .get("/{name}")
         ..
         ..
        .to("direct:x");

查看以下帖子中的答案,但仍然无法解决我得到的异常,

  1. https://stackoverflow.com/a/60598953/6363894
  2. https://stackoverflow.com/a/55499113/6363894

我知道异常清楚地说明了使用org.eclipse.jetty.util.ssl.SslContextFactory$Server,但我不明白如何/在哪里使用 SslContextFactory.Server 对象。

SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStoreResource(findKeyStorePath());
sslContextFactory.setKeyStorePassword("password");
sslContextFactory.setKeyManagerPassword("password");
sslContextFactory.setNeedClientAuth(true); 

我还为 sslContextParameters 创建了一个 bean,并将其添加到 restConfiguration 中,如下所示,这次应用程序运行成功,但是当我测试时,SSL 握手失败。

       restConfiguration()
        .component("jetty")
        .endpointProperty("sslContextParameters", "#sslContextParameters")
        .scheme("https")
        .port("8080");


@Bean(name = "sslContextParameters")
    public SSLContextParameters setSSLContextParameters() {
        
        KeyStoreParameters ksp = new KeyStoreParameters();
        ksp.setResource("keystore-with-multiple-certificates.jks");
        ksp.setPassword("password");

        KeyManagersParameters kmp = new KeyManagersParameters();
        kmp.setKeyStore(ksp);
        kmp.setKeyPassword("password");

        SSLContextServerParameters scsp = new SSLContextServerParameters();
        scsp.setClientAuthentication("REQUIRE");
        
        SSLContextParameters scp = new SSLContextParameters();
        scp.setServerParameters(scsp);
        scp.setKeyManagers(kmp);
        
        return scp;
    }

关于如何使用 restConfigurations() 或任何其他方式配置 SslContextFactory.Server 对象的任何帮助?如果需要更多详细信息,我会更新帖子。

标签: spring-bootsslhttpsapache-cameljetty

解决方案


推荐阅读