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

Spring Security自定义登录出现循环跳转,无法进入目标页面

问题排查与解决方案

1. 缺少CSRF令牌导致POST请求被拦截

Spring Security默认启用CSRF保护,你的登录表单采用POST请求,但未携带CSRF令牌,导致请求被框架拦截,最终跳回登录页且不会触发错误提示参数。

修改登录表单,添加CSRF令牌字段:

<form name="f" method="post" action="/process_login">
  <label for="username">Введите имя пользователя</label>
  <input type="text" name="username" id="username"/>
  <br/>
  <label for="password">Введите пароль</label>
  <input type="password" name="password" id="password"/>
  <br/>
  <!-- 添加CSRF令牌 -->
  <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
  <input type="submit" value="login">

  <div th:if="${param.error}" style="color:royalblue">
      Неверный имя пользователя или пароль
  </div>
</form>

注:同时修正了密码标签的错误文本,不影响功能但优化用户体验。

2. 未配置用户认证数据源

你提到使用数据库中的用户,但当前配置中未提供UserDetailsService或AuthenticationProvider,Spring Security无法验证用户身份,导致认证始终失败。

临时测试方案(内存用户)

在SecurityConfig中添加内存用户配置,快速验证登录流程:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        // 原有配置保持不变
        http.authorizeHttpRequests((authz) -> authz.anyRequest().authenticated())
                .formLogin((form) ->
                        form.loginPage("/auth/login")
                                .loginProcessingUrl("/process_login")
                                .defaultSuccessUrl("/hello", true)
                                .failureUrl("/auth/login?error")
                                .permitAll());

        return http.build();
    }

    @Bean
    public PasswordEncoder encoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    // 添加内存用户
    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails testUser = User.withUsername("test")
                .password("test")
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(testUser);
    }
}

数据库用户方案

如果使用数据库存储用户,需实现UserDetailsService从数据库查询用户信息,示例:

@Service
public class CustomUserDetailsService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository; // 自定义的用户数据访问层

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User dbUser = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("用户不存在: " + username));
        return User.withUsername(dbUser.getUsername())
                .password(dbUser.getPassword())
                .roles(dbUser.getRoles().toArray(new String[0]))
                .build();
    }
}

确保该类被Spring容器管理,框架会自动使用它完成用户认证。

3. 验证基础配置细节

  • 确认defaultSuccessUrl("/hello", true)中的true参数已设置,该参数会强制跳转到指定页面,不受之前请求路径影响。
  • 确保hello.html视图文件存在于正确目录(如使用Thymeleaf时需放在src/main/resources/templates/下)。

完成上述修改后重新启动应用:

  • 输入正确账号密码,将跳转到/hello页面;
  • 输入错误账号密码,会返回登录页并显示错误提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 18:30:35