设置SessionCreationPolicy.STATELESS后仍生成HttpSession的解决方法咨询
解决Spring Security设了STATELESS还生成HttpSession的问题
常见排查点和解决办法
1. 确认配置没被覆盖
你给/v2/**设了STATELESS,但有可能被全局配置或者优先级更高的规则覆盖。比如全局先设置了有状态的Session策略,局部配置就会失效。
- 正确的配置姿势是单独限定
/v2/**的规则,示例:
@Override protected void configure(HttpSecurity http) throws Exception { http .requestMatchers().antMatchers("/v2/**") .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests().anyRequest().permitAll(); }
要是全局和局部配置混写,得保证/v2/**的Session配置是专门针对该路径的,别被其他规则冲掉。
2. 排查其他组件是否偷偷创建Session
Spring Security声明不创建Session,但其他组件可能触发创建:
- 检查项目中的过滤器(Filter),有没有调用
request.getSession()或request.getSession(true)的,这俩方法会强制创建Session,改成request.getSession(false)就只会获取已有Session,不会新建。 - 排查是否使用了
@SessionAttributes、Spring Session自动配置,甚至JSP这类视图模板默认会创建Session,这些都可能触发Session生成。 - 如果是Spring Session导致的问题,可在
application.properties中关闭全局Session存储:
若其他路径仍需Session,可单独给spring.session.store-type=none/v2/**排除Spring Session的过滤器。
3. 多SecurityFilterChain需注意优先级
如果项目存在多个SecurityFilterChain Bean,要保证/v2/**对应的配置优先级更高。用@Order注解指定顺序,数值越小优先级越高:
@Configuration @Order(1) // 该配置先生效 public class V2SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .requestMatchers().antMatchers("/v2/**") .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests().anyRequest().permitAll(); } } @Configuration @Order(2) // 全局配置后生效 public class GlobalSecurityConfig extends WebSecurityConfigurerAdapter { // 其他全局规则配置 }
4. 强制禁用Servlet容器的默认Session创建
部分Servlet容器(如Tomcat)会在特定场景自动创建Session,可全局或针对路径禁用:
- 全局禁用在
application.properties中添加:
若其他路径仍需Session,可写个过滤器,在server.servlet.session.enabled=false/v2/**的请求中设置request.setAttribute("org.apache.catalina.session.SessionCreationEnabled", false)(仅针对Tomcat有效)。
定位Session创建时机的方法
写个简单的过滤器,在请求处理前后检查Session状态,就能找到是哪个环节创建了Session:
@Component public class SessionCheckFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { HttpSession session = request.getSession(false); System.out.println("处理前:是否存在Session?" + (session != null)); filterChain.doFilter(request, response); session = request.getSession(false); System.out.println("处理后:是否存在Session?" + (session != null)); } }
把这个过滤器放到Spring Security过滤器链的最前端,就能清晰看到Session的创建节点。
内容的提问来源于stack exchange,提问作者fujisan
相关产品推荐
相关产品推荐

