问题
以编程方式配置spring引导以使用我的自定义 SSLContext
. 用于MTL。
上下文
spring的文档只提供了一种清晰的方式来配置ssl(通过 application.properties
):
server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=secret
server.ssl.trust-store=classpath:truststore.jks
...
然而,这个解决方案缺乏深度,因为在某些场景中,我想利用定制自己的解决方案 SSLContext
. 例如,将mtls配置为不仅信任通过 keytool
,但同时信任我的自签名证书和放置在java默认信任库中的证书( lib/security/cacerts
).
当然,我可以使用前面提到的 keytool
,但我正在寻找更灵活的方法,因此提供了我自己的方法 SSLContext
.
spring提供了一个关于配置web服务器的部分,其中说使用 TomcatServletWebServerFactory
或者 ConfigurableServletWebServerFactory
,但它们并没有真正深入。
我试着创造一个 Component
:
@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;
}
});
}
}
但无济于事。
1条答案
按热度按时间uhry853o1#
不幸的是,这在spring boot+tomcat中是不可能的。它没有注入sslcontext或其他属性(如sslserversocketfactory、trustmanager或keymanager)的选项。
但是,如果您仍然想使用springboot并想对其进行完全配置,如果您不关心springboot使用的是哪种服务器,我建议您使用jetty。
下面是如何使用spring boot+jetty实现这一点的基本实现:
你还需要告诉spring不要再使用tomcat了,改用jetty。您可以通过将以下代码段添加到pom中来实现这一点: