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

Spring Security遇登录重定向循环,如何获取登录表单?

问题解决:重定向循环与登录表单配置

一、解决重定向循环问题

你的请求出现重定向循环,核心原因有两个:

  1. CSRF保护拦截POST请求:Spring Security默认开启CSRF保护,对于POST请求,若未携带CSRF Token,会被拦截并重定向到登录页,而无状态会话(STATELESS)的配置导致循环重定向。
  2. Form Login配置与RESTful认证冲突:同时配置JWT无状态认证和传统表单登录,两种认证规则相互干扰,导致REST接口请求被错误拦截。

修改SecurityConfig代码如下:

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthFilter;
    private final AuthenticationProvider authenticationProvider;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity)
            throws Exception {

        httpSecurity
                // 禁用CSRF:RESTful API无状态,无需CSRF保护
                .csrf(csrf -> csrf.disable())
                .authorizeRequests(authorize -> authorize
                        .requestMatchers("/api/v3/auth/**").permitAll()
                        .anyRequest().authenticated()
                )
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                )
                .authenticationProvider(authenticationProvider)
                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

        return httpSecurity.build();
    }
}

若确实需要保留传统表单登录功能,需添加视图控制器处理/login请求,同时调整formLogin配置避免干扰REST接口:

// 在SecurityConfig中添加视图控制器配置
@Bean
public WebMvcConfigurer webMvcConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/login").setViewName("login");
        }
    };
}

// 在securityFilterChain中调整formLogin配置
.formLogin(formLogin -> formLogin
        .loginPage("/login")
        .loginProcessingUrl("/api/v3/auth/login") // 指定表单提交的处理路径
        .permitAll()
        .defaultSuccessUrl("/")
)

二、获取登录表单的方式

根据应用架构选择对应方案:

1. 服务器端渲染表单

创建@Controller处理/login请求,返回HTML登录页面:

@Controller
public class LoginController {

    @GetMapping("/login")
    public String showLoginForm() {
        // 返回登录页面视图名称,需确保模板引擎(如Thymeleaf)存在对应的login.html文件
        return "login";
    }
}

2. 前后端分离架构(前端自行构建表单)

前端自行构建登录表单,通过POST请求调用/api/v3/auth/authenticate接口,传递包含用户名和密码的JSON数据,获取JWT Token后,后续请求在请求头中携带Authorization: Bearer {token}完成认证。

示例前端请求(JavaScript):

fetch('/api/v3/auth/authenticate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    username: 'your-username',
    password: 'your-password'
  })
})
.then(response => response.json())
.then(data => {
  localStorage.setItem('token', data.token);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 22:52:27