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

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,形成无限循环。

解决步骤

  1. 给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");
        }
    }
    
  2. 可选:启用@EnableWebSecurity注解
    在SecurityConfig中取消@EnableWebSecurity的注释(Spring Boot 2.7+版本后可自动配置,但显式启用能让配置逻辑更清晰):

    @Configuration
    @EnableWebSecurity // 取消注释
    public class SecurityConfig {
        // 原有代码保持不变
    }
    

完成以上修改后重启应用,访问localhost:8080会正常重定向到/login页面,无限循环问题即可解决。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 16:28:11