Spring Boot启用HSTS后HTTPS请求报Http11Processor解析错误
问题原因与解决方案
问题根源
你遇到的Error parsing HTTP request header错误,本质是HTTPS加密请求被发送到了HTTP端口:
- 当
server.ssl.enabled=true但未正确配置SSL端口或密钥库时,Tomcat的8086端口仍以HTTP协议监听。 - 浏览器发送
https://localhost:8086请求时,会先发送SSL握手的加密数据,但Tomcat用HTTP协议解析这些加密内容,就会把二进制数据识别为乱码的HTTP请求头,触发方法名非法的错误。
修复步骤
1. 完整配置SSL参数
Spring Boot启用HTTPS必须指定密钥库信息(否则Tomcat无法启动SSL端口),在application.properties中补充配置:
# 指定HTTPS端口 server.port=8443 server.ssl.enabled=true server.ssl.protocol=TLS server.ssl.enabled-protocols=TLSv1.2 # 密钥库配置(替换为你的实际密钥库信息) server.ssl.key-store=classpath:your-keystore.p12 server.ssl.key-store-password=your-keystore-password server.ssl.key-store-type=PKCS12 server.ssl.key-alias=your-key-alias
如果你还没有密钥库,可以用JDK的
keytool生成:keytool -genkeypair -alias myalias -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650
2. 调整SecurityFilterChain配置
保持HSTS配置的同时,添加强制HTTPS的规则,最终配置类如下:
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // 启用HSTS,可配置过期时间和子域名包含规则 http.headers() .httpStrictTransportSecurity() .maxAgeInSeconds(31536000) .includeSubDomains(true); // 强制所有请求使用HTTPS http.requiresChannel() .anyRequest() .requiresSecure(); return http.build(); } }
3. 验证访问
启动应用后,使用https://localhost:8443/hello访问,此时请求会被Tomcat以HTTPS协议正确解析,不会再出现解析错误。
可选:配置HTTP转HTTPS
如果需要将8086端口的HTTP请求重定向到HTTPS端口,可以添加额外的HTTP端口配置:
# HTTP端口 server.http.port=8086
然后添加Tomcat Connector配置实现重定向:
import org.apache.catalina.connector.Connector; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class TomcatConfig { @Bean public ServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); tomcat.addAdditionalTomcatConnectors(createHttpConnector()); return tomcat; } private Connector createHttpConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); connector.setPort(8086); connector.setSecure(false); connector.setRedirectPort(8443); return connector; } }
内容的提问来源于stack exchange,提问作者Paul Ga
相关产品推荐
相关产品推荐

