You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加Spring Security配置后TestRestTemplate的postForEntity请求失败

问题根源

你的问题是线程复用导致SecurityContextHolder中的认证信息残留/未正确更新:TestRestTemplate底层客户端使用线程池复用线程,第一个请求处理完成后,线程绑定的SecurityContext未被清理,第二个请求复用该线程时,权限校验逻辑读取了异常的认证信息,导致访问被拒绝;添加sleep后线程池切换新线程,SecurityContext为空,过滤器正常执行并设置正确的认证信息,因此测试通过。


解决方案

方案1:在过滤器中手动清理SecurityContext

修改UserInfoHeaderFilter的doFilterInternal方法,通过try-finally块确保请求结束后强制清理线程绑定的SecurityContext,彻底避免线程复用带来的残留问题:

@Override
protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException {
    try {
        String headerValue = request.getHeader(HEADER_NAME);
        if (headerValue != null && headerValue.startsWith("Bearer ")) {
            setAuthenticationInSecurityContext(headerValue.substring(7));
        }
        filterChain.doFilter(request, response);
    } finally {
        // 强制清理线程绑定的SecurityContext
        SecurityContextHolder.clearContext();
    }
}

方案2:配置NullSecurityContextRepository

显式配置Spring Security使用NullSecurityContextRepository,确保SecurityContext不会被持久化到Session,且每次请求结束后自动清理:
修改SecurityConfig的filterChain方法:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    return http
            .addFilterBefore(userInfoHeaderFilter, BasicAuthenticationFilter.class)
            // 配置SecurityContext不持久化,请求结束自动清理
            .securityContext(context -> context
                    .securityContextRepository(new NullSecurityContextRepository())
            )
            .authorizeHttpRequests(auth -> auth
                    .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**").permitAll()
                    .anyRequest().hasAnyAuthority("SUPER_ADMIN")
            )
            .csrf().disable()
            .build();
}

补充说明

  • Spring Security默认使用ThreadLocalSecurityContextHolderStrategy,将认证信息绑定到当前线程;
  • 你的过滤器未处理请求结束后的SecurityContext清理,且测试场景下默认的SecurityContextPersistenceFilter可能未正确执行清理逻辑;
  • 两种方案都能从根源解决线程复用导致的认证信息残留问题,方案1更直接针对过滤器逻辑,方案2则通过Spring Security的配置统一管理。

内容的提问来源于stack exchange,提问作者Suule

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:45:54