SpringBoot 2.4.2升级至2.7.0后SSL异常导致服务无法启动
问题诊断
异常核心为java.lang.IllegalArgumentException: Multiple certificates were specified and at least one is missing the required attribute type,这是Tomcat 9.0.63版本中SSL配置逻辑变更导致的,与Apache Bugzilla 62803描述场景匹配——显式指定密钥库提供者时,Tomcat的证书注册逻辑误判为多证书场景,触发属性校验失败。
解决步骤
1. 移除不必要的密钥库提供者配置
直接删除application.properties中的server.ssl.key-store-provider=SUN配置:
# 移除该行配置 server.ssl.key-store-provider=SUN
SUN是JDK默认密钥库提供者,显式设置会触发Tomcat新版本的证书校验逻辑,即使密钥库仅含单个证书,也会被误判为多证书场景。
2. 验证密钥库证书完整性
用keytool命令检查密钥库内证书属性,确保所有证书包含必要属性类型:
keytool -list -v -keystore <CERTIFICATE FILE PATH> -storepass <PASSWORD>
重点查看证书的密钥用途、扩展密钥用途等字段,若存在缺失属性的证书,重新生成或导入符合规范的证书。
3. 自定义Tomcat SSL配置(绕过自动配置)
若上述方法无效,可通过代码自定义Tomcat SSL配置,规避SpringBoot自动配置与Tomcat新版本的冲突:
@Configuration public class CustomTomcatSslConfig { @Value("${server.port}") private int sslPort; @Value("${server.ssl.key-store}") private String keystorePath; @Value("${server.ssl.key-store-type}") private String keystoreType; @Value("${server.ssl.key-store-password}") private String keystorePassword; @Value("${server.ssl.key-password}") private String keyPassword; @Value("${server.ssl.key-alias}") private String keyAlias; @Bean public TomcatServletWebServerFactory tomcatSslServerFactory() { TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); factory.addConnectorCustomizers(connector -> { connector.setPort(sslPort); connector.setSecure(true); connector.setScheme("https"); AbstractHttp11Protocol<?> protocol = (AbstractHttp11Protocol<?>) connector.getProtocolHandler(); SSLHostConfig sslHostConfig = new SSLHostConfig(); SSLHostConfigCertificate cert = new SSLHostConfigCertificate(sslHostConfig, SSLHostConfigCertificate.Type.RSA); cert.setKeystoreFile(keystorePath); cert.setKeystoreType(keystoreType); cert.setKeystorePass(keystorePassword); cert.setKeyPass(keyPassword); cert.setKeyAlias(keyAlias); sslHostConfig.addCertificate(cert); protocol.addSslHostConfig(sslHostConfig); }); return factory; } }
使用该配置时,需确保application.properties仅保留必要SSL配置项(已移除server.ssl.key-store-provider)。
补充说明
强制指定Tomcat版本无效的原因:SpringBoot 2.7.0的自动配置逻辑与Tomcat 9.0.63+的SSL处理深度绑定,单纯降级Tomcat版本会破坏SpringBoot依赖兼容性,导致配置逻辑依然冲突。
内容的提问来源于stack exchange,提问作者barasach

