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

Spring REST端点创建会话异常:认证后访问受保护端点被重定向

咱们一步步来排查这个会话认证的问题,大概率是Spring Security的会话配置或者自定义认证端点的处理逻辑没衔接好,我整理了几个常见的遗漏点:

1. 确保自定义认证端点正确完成Spring Security的认证流程

你手动调用session.getSession(true)只是创建了空会话,但Spring Security并没有把这个会话和已认证的用户身份关联起来。这就导致后续请求过来时,Security上下文里没有有效认证信息,自然会触发重定向到登录入口。

  • 你需要在验证用户名密码成功后,手动构建并绑定认证信息到Security上下文和当前会话:
    // 假设已完成用户名密码校验,构建包含权限的Authentication对象
    UsernamePasswordAuthenticationToken authToken = 
        new UsernamePasswordAuthenticationToken(validUsername, null, userAuthorities);
    // 将认证信息存入Security上下文
    SecurityContextHolder.getContext().setAuthentication(authToken);
    // 把上下文持久化到当前会话,让后续请求能读取到
    HttpSessionSecurityContextRepository contextRepo = new HttpSessionSecurityContextRepository();
    contextRepo.saveContext(SecurityContextHolder.getContext(), request, response);
    
  • 注意:务必确保代码里的request和response是当前请求的真实对象,否则会话绑定会失效。

2. 检查Spring Security的会话管理配置

Spring Security默认会接管会话生命周期,但如果你的自定义认证绕开了它的默认流程,需要调整配置来匹配你的手动会话创建逻辑:

Spring Security 5.7之前(含WebSecurityConfigurerAdapter)

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // 配置会话创建策略为按需创建,和你手动调用getSession(true)的逻辑匹配
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .and()
            // 放行自定义登录端点,避免被拦截
            .authorizeRequests()
                .antMatchers("/your-custom-login-endpoint").permitAll()
                .anyRequest().authenticated()
            .and()
            .exceptionHandling()
                .authenticationEntryPoint(yourCustomEntryPoint); // 你的自定义入口点
    }
}

Spring Security 5.7+(无WebSecurityConfigurerAdapter)

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .sessionManagement(sm -> sm
            .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
        )
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/your-custom-login-endpoint").permitAll()
            .anyRequest().authenticated()
        )
        .exceptionHandling(ex -> ex
            .authenticationEntryPoint(yourCustomEntryPoint)
        );
    return http.build();
}

3. 验证JSESSIONID的传递是否正确

  • 确保客户端在请求受保护端点时,正确携带了服务器返回的JSESSIONID Cookie。可以用浏览器开发者工具(Network标签)查看请求头的Cookie字段,确认包含JSESSIONID=xxx的内容。
  • 如果是跨域场景,还要额外配置:
    • Spring Security中开启CORS并允许凭证:http.cors(cors -> cors.configurationSource(corsConfigSource)),其中corsConfigSource要设置allowCredentials(true)。
    • 前端请求需携带凭证,比如axios要设置withCredentials: true。

4. 检查SecurityContext的存储与读取逻辑

Spring Security默认使用HttpSessionSecurityContextRepository来存储SecurityContext,如果你的配置替换了这个组件,或者有自定义过滤器干扰了上下文读取,也会导致认证失败:

  • 不要随意自定义SecurityContextRepository,除非你明确理解其作用;如果已经自定义,要确保它能正确从会话中读取和写入SecurityContext。
  • 检查过滤器链顺序:自定义的认证逻辑(比如你的登录端点)要在Spring Security的核心认证过滤器之前执行,确保后续过滤器能读取到已绑定的认证信息。

如果以上排查都没解决问题,可以提供你的Security配置类完整代码、自定义登录端点的代码,这样能更精准定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:06:46