问题
以编程方式配置 Spring Boot 以使用我的自定义SSLContext
. 并用于 mTLS。
语境
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 的默认 TrustStore ( lib/security/cacerts
) 中的证书。
当然,我可以使用已经提到的组合它们keytool
,但我正在寻找更灵活的方法,因此提供我自己的SSLContext
.
Spring 提供了一个关于配置 Web 服务器的部分,它说使用类似TomcatServletWebServerFactory
or的东西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;
}
});
}
}
但无济于事。