Spring Boot 3.3.4(基于Tomcat)正确配置SNIMatcher的方法咨询
Spring Boot 3.3.4(基于Tomcat)正确配置SNIMatcher的方法咨询
我完全懂你现在的困扰——明明在ServerNameExtension.java里看到了正好符合你需求的SNI匹配逻辑,却找不到正确设置SNIMatchers的入口,尝试用TomcatServletWebServerFactory操作SSLParameters还被忽略,确实挺让人头疼的。
咱们先理清楚问题所在:你之前直接操作certificate.getSslContext()的SSLParameters是行不通的,因为Tomcat在启动初始化连接器时,会自己基于SSLHostConfig的配置重新构建SSLParameters,你手动设置的参数会被覆盖掉。正确的姿势是直接给Tomcat的SSLHostConfig添加SNIMatcher,它会自动把这些匹配器注入到后续的SSL参数里。
给你一个可行的代码示例:
@Bean public WebServerFactoryCustomizer<TomcatServletWebServerFactory> sslSniCustomizer() { return factory -> { factory.addConnectorCustomizers(connector -> { // 获取默认的SSLHostConfig(如果有多域名配置可以遍历处理) SSLHostConfig sslHostConfig = connector.findSslHostConfigs()[0]; // 添加自定义的SNI匹配器,这里实现你的匹配规则 sslHostConfig.addSniMatcher(new SNIMatcher() { @Override public boolean matches(SNIServerName sniServerName) { // 只处理主机名类型的SNI请求 if (sniServerName.getType() == StandardConstants.SNI_HOST_NAME) { SNIHostName sniHostName = (SNIHostName) sniServerName; String hostname = sniHostName.getAsciiName(); // 示例:只允许以.yourdomain.com结尾的域名 return hostname.endsWith(".yourdomain.com"); } return false; } }); // 如果需要多个匹配规则,直接多次调用addSniMatcher即可 // sslHostConfig.addSniMatcher(anotherMatcher); }); }; }
再给你解释下为什么这个方法能生效:
- Tomcat的
SSLHostConfig是管理SSL相关配置的核心载体,你添加的SNIMatcher会被存到它的sniMatchers集合里 - 当握手时,
ServerNameExtension里的chooseSni方法会读取这个集合的匹配器,和你看到的代码逻辑完全对接 - 如果没有匹配到任何SNIMatcher,就会触发你想要的
UNRECOGNIZED_NAME错误,完美符合你的预期
另外要注意:如果你的Tomcat配置了多个SSLHostConfig(比如多证书多域名场景),记得遍历所有的SSLHostConfig来添加匹配器,而不是只取第一个。
内容来源于stack exchange
相关产品推荐
相关产品推荐

