Spring 6.1.x迁移后HTTP请求下request.isSecure()返回true异常求助
问题根源与解决方案
可能的原因
- Tomcat 11默认配置变更:Tomcat 11默认启用了
RemoteIpValve用于处理反向代理转发的请求头,若请求来自本地或被识别为内部代理请求,Tomcat可能错误地将HTTP请求标记为安全(secure)状态,即便实际使用的是HTTP协议。 - 请求头被意外篡改:浏览器插件、本地代理工具如Charles、Fiddler或测试工具可能在请求中添加
X-Forwarded-Proto: https这类头,导致Tomcat误判请求为HTTPS。 - Spring 6.x自动配置影响:Spring 6.x及Spring Boot 3.x的
forward-headers-strategy默认配置会自动处理转发头,若未正确配置,会导致请求的secure状态被错误设置。
排查与解决步骤
检查Tomcat配置
打开Tomcat的conf/server.xml,查看是否存在RemoteIpValve配置。如果未使用反向代理,直接注释或删除该Valve:<!-- 注释掉不需要的RemoteIpValve --> <!-- <Valve className="org.apache.catalina.valves.RemoteIpValve" /> -->若确实使用反向代理,需确保
protocolHeader如X-Forwarded-Proto的实际值为http,并配置internalProxies仅信任合法的代理地址。调整Spring Boot配置(若使用Spring Boot)
在application.properties或application.yml中添加以下配置,禁用转发头自动处理:server.forward-headers-strategy=none或直接关闭Tomcat的RemoteIpValve:
server.tomcat.remoteip.enabled=false排查请求头
在Filter中打印所有请求头,确认是否存在异常的转发头:@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; Enumeration<String> headerNames = httpRequest.getHeaderNames(); while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); System.out.printf("Header: %s = %s%n", name, httpRequest.getHeader(name)); } // 原有逻辑 chain.doFilter(request, response); }若发现
X-Forwarded-Proto等头被设置为https,需排查来源并修正。临时Workaround(治标)
若需快速恢复功能,可手动重置JSESSIONID Cookie的Secure属性:@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; assert "http".equals(httpRequest.getScheme()); HttpSession session = httpRequest.getSession(true); // 重置JSESSIONID Cookie的Secure属性 Cookie[] cookies = httpResponse.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if ("JSESSIONID".equals(cookie.getName())) { cookie.setSecure(false); httpResponse.addCookie(cookie); break; } } } chain.doFilter(request, response); }
内容的提问来源于stack exchange,提问作者Freddy Boucher
相关产品推荐
相关产品推荐

