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
核心原因
你的配置存在两个关键问题:
- 登录页面路径未被匿名访问允许:虽然
.formLogin().permitAll()声明了登录相关接口允许匿名,但/login这个路径本身被anyRequest().authenticated()规则拦截,导致访问/login时,Spring Security要求用户认证,随即重定向到/login,形成无限循环。 - 登录页面路径与实际静态文件路径不匹配:当你添加
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
相关产品推荐
相关产品推荐

