使用TLS与JWT实现登录鉴权时存在安全漏洞,请求排查
问题分析与解决方案
看起来你遇到的问题是HTTP端口(8080)意外允许携带有效JWT的请求访问受保护接口,这违背了你的安全预期——毕竟JWT在HTTP明文传输中存在被窃听、篡改的风险。下面是问题根源和修复方案:
核心问题
你的配置存在两个关键漏洞:
- Spring Security未强制受保护请求使用HTTPS:当前配置只校验JWT的有效性,完全不关心请求的传输协议,所以只要JWT合法,HTTP请求也会被放行。
- Tomcat的安全约束未完全拦截HTTP请求:虽然你配置了
SecurityConstraint设置userConstraint="CONFIDENTIAL",但它的作用是将HTTP请求重定向到HTTPS,而非直接拒绝HTTP请求。如果客户端不跟随重定向,Tomcat仍然会处理HTTP请求,而Spring Security会直接通过JWT校验。
修复方案
1. 增强Spring Security配置,强制HTTPS访问受保护资源
在WebSecurityConfiguration的configure(HttpSecurity http)方法中添加通道安全配置,明确要求所有认证请求必须通过HTTPS传输:
@Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() // 强制所有请求使用HTTPS .requiresChannel() .anyRequest().requiresSecure() .and() .authorizeRequests() .antMatchers("/login").permitAll() // 若想强制/login也用HTTPS,可移除该行 .anyRequest().authenticated() .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); http.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class); }
强烈推荐连
/login接口也强制HTTPS,避免用户密码在HTTP中明文传输,只需移除.antMatchers("/login").permitAll()的特殊处理即可。
这个配置会直接拒绝HTTP协议的受保护请求(返回403 Forbidden),或者自动重定向到HTTPS端口,完全符合你的安全预期。
2. (可选)在JWT过滤器中添加HTTPS校验
为了双重保险,你可以在JwtTokenFilter的doFilterInternal方法中添加协议校验逻辑,直接拒绝非HTTPS的认证请求:
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 检查请求是否为HTTPS if (!request.isSecure()) { response.sendError(HttpServletResponse.SC_FORBIDDEN, "HTTPS is required for authenticated requests"); return; } // 原有的JWT校验逻辑... String token = extractTokenFromRequest(request); // ...后续校验代码 }
3. 优化Tomcat配置(可选)
确保Tomcat的HTTP连接器配置正确,让重定向行为更可靠:
private Connector getHttpConnector() { Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL); connector.setScheme("http"); connector.setPort(8080); connector.setSecure(false); connector.setRedirectPort(8443); // 显式配置重定向端口,强化HTTP转HTTPS的行为 connector.setProperty("redirectPort", "8443"); return connector; }
验证效果
修改配置后:
- 通过
https://localhost:8443/login获取JWT后,访问https://localhost:8443/welcome依然正常。 - 直接访问
http://localhost:8080/welcome(无论是否携带JWT)都会被Spring Security拒绝,返回403或重定向到HTTPS。
内容的提问来源于stack exchange,提问作者Leo S
相关产品推荐
相关产品推荐

