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

Java Spring访问/login出现ERR_TOO_MANY_REDIRECTS问题求助

问题分析与解决:Spring Security登录页面重定向循环(ERR_TOO_MANY_REDIRECTS)

问题复现

  • 访问http://localhost:8080/login时出现ERR_TOO_MANY_REDIRECTS,响应码302
  • 添加login.html后,/login.html可正常访问,但访问/api/v1/registration/会被重定向到/login.html
  • 移除.formLogin(...)配置段后,注册接口返回403 Forbidden

核心原因

你的配置存在两个关键问题:

  1. 登录页面路径未被匿名访问允许:虽然.formLogin().permitAll()声明了登录相关接口允许匿名,但/login这个路径本身被anyRequest().authenticated()规则拦截,导致访问/login时,Spring Security要求用户认证,随即重定向到/login,形成无限循环。
  2. 登录页面路径与实际静态文件路径不匹配:当你添加login.html后,Spring Security默认找不到/login对应的资源,会自动调整重定向目标,但此时注册接口的权限规则也因为登录路径的问题出现异常。

解决方案

1. 允许匿名访问登录页面路径

在authorizeHttpRequests中添加对/login路径的放行规则,确保匿名用户能直接访问登录页面:

.authorizeHttpRequests(authorize -> authorize
        .requestMatchers("/api/v*/registration/**", "/login").permitAll()
        .anyRequest().authenticated()
)

2. 确保登录页面路径与实际资源匹配

如果你的登录页面是静态文件login.html,有两种处理方式:

  • 方式一:直接将loginPage配置为/login.html,同时放行该路径:
.formLogin(formLogin -> formLogin
        .loginPage("/login.html")
        .permitAll()
)

同时在requestMatchers中添加/login.html的放行:

.requestMatchers("/api/v*/registration/**", "/login.html").permitAll()
  • 方式二:通过控制器映射/login到login.html:
    创建一个简单的控制器类:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class LoginController {
    @GetMapping("/login")
    public String showLoginPage() {
        return "login"; // 对应templates下的login.html(如果用Thymeleaf)或静态资源目录下的login.html
    }
}

3. 简化AuthenticationManager配置

不需要手动获取AuthenticationManagerBuilder添加认证提供者,因为DaoAuthenticationProvider已经被声明为Bean,Spring Security会自动识别并使用它,可删除以下代码:

AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
authenticationManagerBuilder.authenticationProvider(daoAuthenticationProvider());

修改后的完整配置代码

import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@AllArgsConstructor
@EnableWebSecurity
public class WebSecurityConfig {

    private final AppUserService appUserService;
    private final BCryptPasswordEncoder passwordEncoder;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers("/api/v*/registration/**", "/login").permitAll()
                        .anyRequest().authenticated()
                )
                .formLogin(formLogin -> formLogin
                        .loginPage("/login")
                        .permitAll()
                );

        return http.build();
    }

    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setPasswordEncoder(passwordEncoder);
        provider.setUserDetailsService(appUserService);
        return provider;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 14:27:35