Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 配置Spring Boot';以编程方式使用自定义SSLContext的 问题_Java_Spring_Spring Boot_Sslcontext_Mtls - Fatal编程技术网

Java 配置Spring Boot';以编程方式使用自定义SSLContext的 问题

Java 配置Spring Boot';以编程方式使用自定义SSLContext的 问题,java,spring,spring-boot,sslcontext,mtls,Java,Spring,Spring Boot,Sslcontext,Mtls,以编程方式配置Spring引导以使用我的自定义SSLContext。并用于MTL 上下文 Spring只提供了一种明确的方式来配置SSL(通过application.properties): 然而,这个解决方案缺乏深度,因为在某些情况下,我想利用定制自己的SSLContext的优势。例如,将MTL配置为不仅信任通过keytool生成的单个证书,而且信任我的自签名证书和放置在Java默认信任库中的证书(lib/security/cacerts) 当然,我可以使用前面提到的keytool组合它们,但

以编程方式配置Spring引导以使用我的自定义
SSLContext
。并用于MTL

上下文 Spring只提供了一种明确的方式来配置SSL(通过
application.properties
):

然而,这个解决方案缺乏深度,因为在某些情况下,我想利用定制自己的
SSLContext
的优势。例如,将MTL配置为不仅信任通过
keytool
生成的单个证书,而且信任我的自签名证书和放置在Java默认信任库中的证书(
lib/security/cacerts

当然,我可以使用前面提到的
keytool
组合它们,但我正在寻找更灵活的方法,因此提供了我自己的
SSLContext

Spring提供了关于的一节,其中说使用类似于
TomcatServletWebServerFactory
ConfigurableServletWebServerFactory
的内容,但它们并没有真正深入

我已尝试创建
组件

@Component
public class CustomServletCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

    private static final String SERVER_CERTIFICATE_PATH = "identity.jks";
    private static final char[] PASSWORD = "secret".toCharArray();

    private static final String CLIENT_CERTIFICATE_PATH = "certs/client.cer";

    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {
        factory.setSslStoreProvider(new SslStoreProvider() {
            @Override
            public KeyStore getKeyStore() throws Exception {
                var certificateAsInputStream = this.getClass().getClassLoader().getResourceAsStream(SERVER_CERTIFICATE_PATH);
                var keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                keyStore.load(certificateAsInputStream, PASSWORD);

                return keyStore;
            }

            @Override
            public KeyStore getTrustStore() throws Exception {
                var keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                keyStore.load(null);
                var organisationRootCertBytes = this.getClass().getClassLoader().getResourceAsStream(CLIENT_CERTIFICATE_PATH).readAllBytes();
                var certificateFactory = CertificateFactory.getInstance("X.509");
                var certificate = certificateFactory.generateCertificate(new ByteArrayInputStream(organisationRootCertBytes));
                keyStore.setCertificateEntry("server", certificate);

                return keyStore;
            }
        });
    }
}
@组件
公共类CustomServletCustomizer实现WebServerFactoryCustomizer{
私有静态最终字符串服务器\u证书\u PATH=“identity.jks”;
私有静态final char[]PASSWORD=“secret”.toCharArray();
私有静态最终字符串CLIENT\u CERTIFICATE\u PATH=“certs/CLIENT.cer”;
@凌驾
public void自定义(ConfigurableServletWebServerFactory){
factory.setSslStoreProvider(新的SslStoreProvider(){
@凌驾
公共密钥库getKeyStore()引发异常{
var certificateAInputStream=this.getClass().getClassLoader().getResourceAsStream(服务器\证书\路径);
var keyStore=keyStore.getInstance(keyStore.getDefaultType());
加载(CertificateAInputStream、密码);
返回密钥库;
}
@凌驾
公共密钥库getTrustStore()引发异常{
var keyStore=keyStore.getInstance(keyStore.getDefaultType());
keyStore.load(null);
var OrganizationRootCertBytes=this.getClass().getClassLoader().getResourceAsStream(客户端证书路径).readAllBytes();
var certificateFactory=certificateFactory.getInstance(“X.509”);
var certificate=certificateFactory.generateCertificate(新的ByteArrayInputStream(OrganizationRootCertBytes));
setCertificateEntry(“服务器”,证书);
返回密钥库;
}
});
}
}

但是没有用。

不幸的是,这在Spring Boot+Tomcat中是不可能的。它没有插入SSLContext或其他属性(如SSLServerSocketFactory或TrustManager或KeyManager)的选项

但是,如果您仍然想使用SpringBoot并希望对其进行全面配置,如果您不关心SpringBoot使用的是哪种服务器,我建议您使用Jetty

以下是使用Spring Boot+Jetty实现此功能的基本实现:

import org.eclipse.jetty.server.Connector;
导入org.eclipse.jetty.server.server;
导入org.eclipse.jetty.server.ServerConnector;
导入org.eclipse.jetty.util.ssl.SslContextFactory;
导入org.springframework.boot.SpringApplication;
导入org.springframework.boot.autoconfigure.springboot应用程序;
导入org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
导入org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
导入org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
导入org.springframework.context.annotation.Bean;
导入java.util.Collections;
@SpringBoot应用程序
公共类应用程序{
公共静态void main(字符串[]args){
SpringApplication.run(App.class,args);
}
@豆子
公共SslContextFactory.Server SslContextFactory(){
SslContextFactory.Server SslContextFactory=新的SslContextFactory.Server();
setsslcontextfactory.setSslContext(sslContext);
sslContextFactory.setIncludeProtocols(协议);
sslContextFactory.setIncludecipherSuite(密码);
sslContextFactory.setNeedClientAuth(true);
返回sslContextFactory;
}
@豆子
公共配置ServletWebServerFactory webServerFactory(SslContextFactory.Server SslContextFactory){
JettyServletWebServerFactory=新的JettyServletWebServerFactory();
工厂设置端口(8443);
JettyServerCustomizer JettyServerCustomizer=server->server.setConnectors(新连接器[]{new ServerConnector(服务器,sslContextFactory)});
setServerCustomizer(Collections.singletonList(jettyServerCustomizer));
返回工厂;
}
}
您还需要告诉spring不再使用tomcat,并切换到jetty。您可以通过将以下代码段添加到pom中来实现这一点:


org.springframework.boot
SpringBootStarterWeb
org.springframework.boot
弹簧启动机tomcat
org.springframework.boot
弹簧靴起动器码头
@Component
public class CustomServletCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

    private static final String SERVER_CERTIFICATE_PATH = "identity.jks";
    private static final char[] PASSWORD = "secret".toCharArray();

    private static final String CLIENT_CERTIFICATE_PATH = "certs/client.cer";

    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {
        factory.setSslStoreProvider(new SslStoreProvider() {
            @Override
            public KeyStore getKeyStore() throws Exception {
                var certificateAsInputStream = this.getClass().getClassLoader().getResourceAsStream(SERVER_CERTIFICATE_PATH);
                var keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                keyStore.load(certificateAsInputStream, PASSWORD);

                return keyStore;
            }

            @Override
            public KeyStore getTrustStore() throws Exception {
                var keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                keyStore.load(null);
                var organisationRootCertBytes = this.getClass().getClassLoader().getResourceAsStream(CLIENT_CERTIFICATE_PATH).readAllBytes();
                var certificateFactory = CertificateFactory.getInstance("X.509");
                var certificate = certificateFactory.generateCertificate(new ByteArrayInputStream(organisationRootCertBytes));
                keyStore.setCertificateEntry("server", certificate);

                return keyStore;
            }
        });
    }
}