Spring Security无法访问自定义登录页:重定向循环问题排查
问题描述
已配置MvcConfig、SecurityConfig及login.html页面,访问localhost:8080时会重定向至localhost:8080/login,但Firefox提示页面存在无限重定向无法加载。请问该问题是否由重定向循环导致?如何解决?
相关代码
MvcConfig.java
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; public class MvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("home"); registry.addViewController("/home").setViewName("home"); registry.addViewController("/hello").setViewName("hello"); registry.addViewController("/login").setViewName("login"); } }
SecurityConfig.java
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; @Configuration //@EnableWebSecurity public class SecurityConfig { @Bean public static PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(req -> req .requestMatchers("/", "/home").permitAll() .anyRequest().authenticated() ).formLogin(form -> form .loginPage("/login") .permitAll() ).logout(logout -> logout .permitAll() ); return http.build(); } @Bean public UserDetailsService userDetailsService() { UserDetails user = User.builder() .username("user") .password(passwordEncoder().encode("password")) .roles("USER") .build(); return new InMemoryUserDetailsManager(user); } }
login.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous"> <script defer src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script> </head> <body> <div th:if="${param.error}"> Invalid username and password </div> <div th:if="${param.logout}"> You have been logged out </div> <form th:action="@{/login}" method="post"> <div> <label for="username">User Name:</label> <input type="text" id="username" name="username"> </div> <div> <label for="password">Password:</label> <input type="text" name="password" id="password"> </div> <button>Submit</button> </form> </body> </html>
问题分析与解决办法
问题原因
确实是重定向循环导致的问题。核心原因是MvcConfig类没有被Spring容器识别并加载,导致/login路径没有对应的视图控制器映射。当Spring Security将未认证请求重定向到/login时,由于该路径未被MvcConfig处理,Spring会判定这是需要认证的请求,再次触发重定向到/login,形成无限循环。
解决步骤
给MvcConfig添加@Configuration注解
修改MvcConfig.java,添加org.springframework.context.annotation.Configuration注解,让Spring扫描并加载这个配置类,确保/login路径能正确映射到login.html视图:import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration // 添加该注解 public class MvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("home"); registry.addViewController("/home").setViewName("home"); registry.addViewController("/hello").setViewName("hello"); registry.addViewController("/login").setViewName("login"); } }可选:启用@EnableWebSecurity注解
在SecurityConfig中取消@EnableWebSecurity的注释(Spring Boot 2.7+版本后可自动配置,但显式启用能让配置逻辑更清晰):@Configuration @EnableWebSecurity // 取消注释 public class SecurityConfig { // 原有代码保持不变 }
完成以上修改后重启应用,访问localhost:8080会正常重定向到/login页面,无限循环问题即可解决。
内容的提问来源于stack exchange,提问作者milanHrabos
相关产品推荐
相关产品推荐

