Java Spring MVC、Spring安全性:无法加载登录模板

Java Spring MVC、Spring安全性:无法加载登录模板,java,spring,spring-mvc,spring-boot,spring-security,Java,Spring,Spring Mvc,Spring Boot,Spring Security,当访问任何路由时,我会被重定向到我的登录页面,包括访问我的登录页面,这是预期的。现在的问题是登录页面甚至没有加载。我已经配置了控制器方法、hander、模板配置和安全配置,这些都是实现此功能所必需的,但我得到的只是以下错误: UserController.java @Controller public class UserController { @Autowired private UserService userService; @GetMapping("/si

当访问任何路由时,我会被重定向到我的登录页面,包括访问我的登录页面,这是预期的。现在的问题是登录页面甚至没有加载。我已经配置了控制器方法、hander、模板配置和安全配置,这些都是实现此功能所必需的,但我得到的只是以下错误:

UserController.java

@Controller
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/signup")
    public String signup(Model model) {
        model.addAttribute("user", new User());
        return "signup";
    }

    @PostMapping("/users")
    public String createUser(User user) {
        // only create user if it does not exist
        if (userService.findByUsername(user.getUsername()) == null) {
            user.setRoles(new String[] {"ROLE_USER"});
            userService.save(user);
            return "redirect:/login";
        }
        else {
            return "redirect:/signup";
        }
    }

    @GetMapping("/login")
    public String login(Model model) {
        model.addAttribute("user", new User());
        return "login";
    }

    @GetMapping("/profile")
    public String currentUserProfile(Model model) {
        User currentUser = (User) model.asMap().get("currentUser");
        model.addAttribute("user", currentUser);
        model.addAttribute("authorized", true);
        return "profile";
    }

    @GetMapping("/users/{id}")
    public String userProfile(@PathVariable Long id, Model model) {
        User queriedUser = userService.findOne(id);
        model.addAttribute("user", queriedUser);

        User currentUser = (User) model.asMap().get("currentUser");
        if (currentUser != null && currentUser.isAdmin()) {
            model.addAttribute("authorized", true);
        }

        return "profile";
    }
}
@ControllerAdvice(basePackages = "com.valencra.recipes.web.controller")
public class UserHandler {
    public static final String USERNAME_NOT_FOUND_ERR_MSG = "Unable to find username";
    public static final String ACCESS_DENIED_ERR_MSG = "Login to use the app";

    @Autowired
    private UserService userService;

    @ModelAttribute("authenticatedUser")
    public User addAuthenticatedUser() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication != null) {
            String username = authentication.getName();
            User user = userService.findByUsername(username);
            if (user != null) {
                return user;
            }
            else {
                throw new UsernameNotFoundException(USERNAME_NOT_FOUND_ERR_MSG);
            }
        }
        else {
            throw new AccessDeniedException(ACCESS_DENIED_ERR_MSG);
        }
    }

    @ExceptionHandler(AccessDeniedException.class)
    public String redirectIfUserNotAuthenticated(RedirectAttributes redirectAttributes) {
        redirectAttributes.addAttribute("errorMessage", ACCESS_DENIED_ERR_MSG);
    return "redirect:/login";
    }

    @ExceptionHandler(UsernameNotFoundException.class)
    public String redirectIfUserNotFound(RedirectAttributes redirectAttributes) {
        redirectAttributes.addAttribute("errorMessage", USERNAME_NOT_FOUND_ERR_MSG);
        return "redirect:/login";
    }
}
@Configuration
public class TemplateConfig {
    @Bean
    public SpringResourceTemplateResolver templateResolver() {
        final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setPrefix("classpath:/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode("LEGACYHTML5");
        return templateResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        final SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
        springTemplateEngine.addTemplateResolver(templateResolver());
        springTemplateEngine.addDialect(new SpringSecurityDialect());
        return springTemplateEngine;
    }

    @Bean
    public ThymeleafViewResolver viewResolver() {
        final ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        viewResolver.setOrder(1);
        return viewResolver;
    }
}
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private RecipesAppUserDetailsService recipesAppUserDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth.userDetailsService(recipesAppUserDetailsService)
            .passwordEncoder(User.PASSWORD_ENCODER);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
          .antMatchers("/signup").permitAll()
          .anyRequest().authenticated()
          .and()
          .formLogin()
          .loginPage("/login")
          .permitAll()
          .successHandler(loginSuccessHandler())
          .failureHandler(loginFailureHandler())
          .and()
          .logout()
          .permitAll()
          .logoutSuccessUrl("/login")
          .and()
          .csrf().disable();

        http.headers().frameOptions().disable();
    }

    public AuthenticationSuccessHandler loginSuccessHandler() {
        return (request, response, authentication) -> response.sendRedirect("/");
    }

    public AuthenticationFailureHandler loginFailureHandler() {
        return (request, response, exception) ->       
        response.sendRedirect("/login");
    }

    @Bean
    public EvaluationContextExtension securityExtension() {
        return new EvaluationContextExtensionSupport() {
            @Override
            public String getExtensionId() {
                return "security";
            }

             @Override
             public Object getRootObject() {
                 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                return new SecurityExpressionRoot(authentication) {};
            }
        };
    }
}
UserHandler.java

@Controller
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/signup")
    public String signup(Model model) {
        model.addAttribute("user", new User());
        return "signup";
    }

    @PostMapping("/users")
    public String createUser(User user) {
        // only create user if it does not exist
        if (userService.findByUsername(user.getUsername()) == null) {
            user.setRoles(new String[] {"ROLE_USER"});
            userService.save(user);
            return "redirect:/login";
        }
        else {
            return "redirect:/signup";
        }
    }

    @GetMapping("/login")
    public String login(Model model) {
        model.addAttribute("user", new User());
        return "login";
    }

    @GetMapping("/profile")
    public String currentUserProfile(Model model) {
        User currentUser = (User) model.asMap().get("currentUser");
        model.addAttribute("user", currentUser);
        model.addAttribute("authorized", true);
        return "profile";
    }

    @GetMapping("/users/{id}")
    public String userProfile(@PathVariable Long id, Model model) {
        User queriedUser = userService.findOne(id);
        model.addAttribute("user", queriedUser);

        User currentUser = (User) model.asMap().get("currentUser");
        if (currentUser != null && currentUser.isAdmin()) {
            model.addAttribute("authorized", true);
        }

        return "profile";
    }
}
@ControllerAdvice(basePackages = "com.valencra.recipes.web.controller")
public class UserHandler {
    public static final String USERNAME_NOT_FOUND_ERR_MSG = "Unable to find username";
    public static final String ACCESS_DENIED_ERR_MSG = "Login to use the app";

    @Autowired
    private UserService userService;

    @ModelAttribute("authenticatedUser")
    public User addAuthenticatedUser() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication != null) {
            String username = authentication.getName();
            User user = userService.findByUsername(username);
            if (user != null) {
                return user;
            }
            else {
                throw new UsernameNotFoundException(USERNAME_NOT_FOUND_ERR_MSG);
            }
        }
        else {
            throw new AccessDeniedException(ACCESS_DENIED_ERR_MSG);
        }
    }

    @ExceptionHandler(AccessDeniedException.class)
    public String redirectIfUserNotAuthenticated(RedirectAttributes redirectAttributes) {
        redirectAttributes.addAttribute("errorMessage", ACCESS_DENIED_ERR_MSG);
    return "redirect:/login";
    }

    @ExceptionHandler(UsernameNotFoundException.class)
    public String redirectIfUserNotFound(RedirectAttributes redirectAttributes) {
        redirectAttributes.addAttribute("errorMessage", USERNAME_NOT_FOUND_ERR_MSG);
        return "redirect:/login";
    }
}
@Configuration
public class TemplateConfig {
    @Bean
    public SpringResourceTemplateResolver templateResolver() {
        final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setPrefix("classpath:/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode("LEGACYHTML5");
        return templateResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        final SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
        springTemplateEngine.addTemplateResolver(templateResolver());
        springTemplateEngine.addDialect(new SpringSecurityDialect());
        return springTemplateEngine;
    }

    @Bean
    public ThymeleafViewResolver viewResolver() {
        final ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        viewResolver.setOrder(1);
        return viewResolver;
    }
}
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private RecipesAppUserDetailsService recipesAppUserDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth.userDetailsService(recipesAppUserDetailsService)
            .passwordEncoder(User.PASSWORD_ENCODER);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
          .antMatchers("/signup").permitAll()
          .anyRequest().authenticated()
          .and()
          .formLogin()
          .loginPage("/login")
          .permitAll()
          .successHandler(loginSuccessHandler())
          .failureHandler(loginFailureHandler())
          .and()
          .logout()
          .permitAll()
          .logoutSuccessUrl("/login")
          .and()
          .csrf().disable();

        http.headers().frameOptions().disable();
    }

    public AuthenticationSuccessHandler loginSuccessHandler() {
        return (request, response, authentication) -> response.sendRedirect("/");
    }

    public AuthenticationFailureHandler loginFailureHandler() {
        return (request, response, exception) ->       
        response.sendRedirect("/login");
    }

    @Bean
    public EvaluationContextExtension securityExtension() {
        return new EvaluationContextExtensionSupport() {
            @Override
            public String getExtensionId() {
                return "security";
            }

             @Override
             public Object getRootObject() {
                 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                return new SecurityExpressionRoot(authentication) {};
            }
        };
    }
}
TemplateConfig.java

@Controller
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/signup")
    public String signup(Model model) {
        model.addAttribute("user", new User());
        return "signup";
    }

    @PostMapping("/users")
    public String createUser(User user) {
        // only create user if it does not exist
        if (userService.findByUsername(user.getUsername()) == null) {
            user.setRoles(new String[] {"ROLE_USER"});
            userService.save(user);
            return "redirect:/login";
        }
        else {
            return "redirect:/signup";
        }
    }

    @GetMapping("/login")
    public String login(Model model) {
        model.addAttribute("user", new User());
        return "login";
    }

    @GetMapping("/profile")
    public String currentUserProfile(Model model) {
        User currentUser = (User) model.asMap().get("currentUser");
        model.addAttribute("user", currentUser);
        model.addAttribute("authorized", true);
        return "profile";
    }

    @GetMapping("/users/{id}")
    public String userProfile(@PathVariable Long id, Model model) {
        User queriedUser = userService.findOne(id);
        model.addAttribute("user", queriedUser);

        User currentUser = (User) model.asMap().get("currentUser");
        if (currentUser != null && currentUser.isAdmin()) {
            model.addAttribute("authorized", true);
        }

        return "profile";
    }
}
@ControllerAdvice(basePackages = "com.valencra.recipes.web.controller")
public class UserHandler {
    public static final String USERNAME_NOT_FOUND_ERR_MSG = "Unable to find username";
    public static final String ACCESS_DENIED_ERR_MSG = "Login to use the app";

    @Autowired
    private UserService userService;

    @ModelAttribute("authenticatedUser")
    public User addAuthenticatedUser() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication != null) {
            String username = authentication.getName();
            User user = userService.findByUsername(username);
            if (user != null) {
                return user;
            }
            else {
                throw new UsernameNotFoundException(USERNAME_NOT_FOUND_ERR_MSG);
            }
        }
        else {
            throw new AccessDeniedException(ACCESS_DENIED_ERR_MSG);
        }
    }

    @ExceptionHandler(AccessDeniedException.class)
    public String redirectIfUserNotAuthenticated(RedirectAttributes redirectAttributes) {
        redirectAttributes.addAttribute("errorMessage", ACCESS_DENIED_ERR_MSG);
    return "redirect:/login";
    }

    @ExceptionHandler(UsernameNotFoundException.class)
    public String redirectIfUserNotFound(RedirectAttributes redirectAttributes) {
        redirectAttributes.addAttribute("errorMessage", USERNAME_NOT_FOUND_ERR_MSG);
        return "redirect:/login";
    }
}
@Configuration
public class TemplateConfig {
    @Bean
    public SpringResourceTemplateResolver templateResolver() {
        final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setPrefix("classpath:/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode("LEGACYHTML5");
        return templateResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        final SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
        springTemplateEngine.addTemplateResolver(templateResolver());
        springTemplateEngine.addDialect(new SpringSecurityDialect());
        return springTemplateEngine;
    }

    @Bean
    public ThymeleafViewResolver viewResolver() {
        final ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        viewResolver.setOrder(1);
        return viewResolver;
    }
}
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private RecipesAppUserDetailsService recipesAppUserDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth.userDetailsService(recipesAppUserDetailsService)
            .passwordEncoder(User.PASSWORD_ENCODER);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
          .antMatchers("/signup").permitAll()
          .anyRequest().authenticated()
          .and()
          .formLogin()
          .loginPage("/login")
          .permitAll()
          .successHandler(loginSuccessHandler())
          .failureHandler(loginFailureHandler())
          .and()
          .logout()
          .permitAll()
          .logoutSuccessUrl("/login")
          .and()
          .csrf().disable();

        http.headers().frameOptions().disable();
    }

    public AuthenticationSuccessHandler loginSuccessHandler() {
        return (request, response, authentication) -> response.sendRedirect("/");
    }

    public AuthenticationFailureHandler loginFailureHandler() {
        return (request, response, exception) ->       
        response.sendRedirect("/login");
    }

    @Bean
    public EvaluationContextExtension securityExtension() {
        return new EvaluationContextExtensionSupport() {
            @Override
            public String getExtensionId() {
                return "security";
            }

             @Override
             public Object getRootObject() {
                 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                return new SecurityExpressionRoot(authentication) {};
            }
        };
    }
}
SecurityConfig.java

@Controller
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/signup")
    public String signup(Model model) {
        model.addAttribute("user", new User());
        return "signup";
    }

    @PostMapping("/users")
    public String createUser(User user) {
        // only create user if it does not exist
        if (userService.findByUsername(user.getUsername()) == null) {
            user.setRoles(new String[] {"ROLE_USER"});
            userService.save(user);
            return "redirect:/login";
        }
        else {
            return "redirect:/signup";
        }
    }

    @GetMapping("/login")
    public String login(Model model) {
        model.addAttribute("user", new User());
        return "login";
    }

    @GetMapping("/profile")
    public String currentUserProfile(Model model) {
        User currentUser = (User) model.asMap().get("currentUser");
        model.addAttribute("user", currentUser);
        model.addAttribute("authorized", true);
        return "profile";
    }

    @GetMapping("/users/{id}")
    public String userProfile(@PathVariable Long id, Model model) {
        User queriedUser = userService.findOne(id);
        model.addAttribute("user", queriedUser);

        User currentUser = (User) model.asMap().get("currentUser");
        if (currentUser != null && currentUser.isAdmin()) {
            model.addAttribute("authorized", true);
        }

        return "profile";
    }
}
@ControllerAdvice(basePackages = "com.valencra.recipes.web.controller")
public class UserHandler {
    public static final String USERNAME_NOT_FOUND_ERR_MSG = "Unable to find username";
    public static final String ACCESS_DENIED_ERR_MSG = "Login to use the app";

    @Autowired
    private UserService userService;

    @ModelAttribute("authenticatedUser")
    public User addAuthenticatedUser() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication != null) {
            String username = authentication.getName();
            User user = userService.findByUsername(username);
            if (user != null) {
                return user;
            }
            else {
                throw new UsernameNotFoundException(USERNAME_NOT_FOUND_ERR_MSG);
            }
        }
        else {
            throw new AccessDeniedException(ACCESS_DENIED_ERR_MSG);
        }
    }

    @ExceptionHandler(AccessDeniedException.class)
    public String redirectIfUserNotAuthenticated(RedirectAttributes redirectAttributes) {
        redirectAttributes.addAttribute("errorMessage", ACCESS_DENIED_ERR_MSG);
    return "redirect:/login";
    }

    @ExceptionHandler(UsernameNotFoundException.class)
    public String redirectIfUserNotFound(RedirectAttributes redirectAttributes) {
        redirectAttributes.addAttribute("errorMessage", USERNAME_NOT_FOUND_ERR_MSG);
        return "redirect:/login";
    }
}
@Configuration
public class TemplateConfig {
    @Bean
    public SpringResourceTemplateResolver templateResolver() {
        final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setPrefix("classpath:/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode("LEGACYHTML5");
        return templateResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        final SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
        springTemplateEngine.addTemplateResolver(templateResolver());
        springTemplateEngine.addDialect(new SpringSecurityDialect());
        return springTemplateEngine;
    }

    @Bean
    public ThymeleafViewResolver viewResolver() {
        final ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        viewResolver.setOrder(1);
        return viewResolver;
    }
}
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private RecipesAppUserDetailsService recipesAppUserDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth.userDetailsService(recipesAppUserDetailsService)
            .passwordEncoder(User.PASSWORD_ENCODER);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
          .antMatchers("/signup").permitAll()
          .anyRequest().authenticated()
          .and()
          .formLogin()
          .loginPage("/login")
          .permitAll()
          .successHandler(loginSuccessHandler())
          .failureHandler(loginFailureHandler())
          .and()
          .logout()
          .permitAll()
          .logoutSuccessUrl("/login")
          .and()
          .csrf().disable();

        http.headers().frameOptions().disable();
    }

    public AuthenticationSuccessHandler loginSuccessHandler() {
        return (request, response, authentication) -> response.sendRedirect("/");
    }

    public AuthenticationFailureHandler loginFailureHandler() {
        return (request, response, exception) ->       
        response.sendRedirect("/login");
    }

    @Bean
    public EvaluationContextExtension securityExtension() {
        return new EvaluationContextExtensionSupport() {
            @Override
            public String getExtensionId() {
                return "security";
            }

             @Override
             public Object getRootObject() {
                 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                return new SecurityExpressionRoot(authentication) {};
            }
        };
    }
}
应用程序属性

# Package where our entities (models) are located
recipes.entity.package = com.valencra.recipes.model

# Details for our datasource
recipes.db.driver = org.h2.Driver
recipes.db.url = jdbc:h2:mem:recipes

# Hibernate properties
hibernate.dialect = org.hibernate.dialect.H2Dialect
hibernate.implicit_naming_strategy = org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
hibernate.format_sql = true
hibernate.show_sql = true
hibernate.hbm2ddl.auto = create-drop

spring.data.rest.basePath=/api/v1
资源目录


编辑:请参阅@lgaleazzi的答案以及随后的评论。基本上,删除UserHandler类可以修复它。

尝试将以下方法添加到
SecurityConfig

@Override
public void configure(WebSecurity web) throws Exception {
    // configuring here URLs for which security filters
    // will be disabled (this is equivalent to using
    // security="none")
    web.ignoring().antMatchers("/login");
}
您可以在应用程序中指定不应应用身份验证的URL(对于静态资源也很有用)


在您的情况下,
/login
未被排除在身份验证范围之外,因此它会导致再次重定向到
/login
,您会遇到一个恶性循环。

尝试将以下方法添加到
SecurityConfig

@Override
public void configure(WebSecurity web) throws Exception {
    // configuring here URLs for which security filters
    // will be disabled (this is equivalent to using
    // security="none")
    web.ignoring().antMatchers("/login");
}
您可以在应用程序中指定不应应用身份验证的URL(对于静态资源也很有用)


在您的情况下,
/login
未被排除在身份验证范围之外,因此它会导致再次重定向到
/login
,从而导致恶性循环。

堆栈跟踪说明了什么

查看UserHandler,您可以处理一个空的经过身份验证的对象,以及一个可以找到的用户。你不能处理匿名用户的情况。我想这就是问题所在


如果没有人经过身份验证,您将获得一个匿名用户的身份验证对象。您可以使用isAuthenticated()方法检查。但实际上您不必编写此代码,Spring Boot通过其默认配置可以很好地处理所有这些问题。

堆栈跟踪说明了什么

查看UserHandler,您可以处理一个空的经过身份验证的对象,以及一个可以找到的用户。你不能处理匿名用户的情况。我想这就是问题所在


如果没有人经过身份验证,您将获得一个匿名用户的身份验证对象。您可以使用isAuthenticated()方法检查。但是您实际上不必编写此代码,Spring Boot在其默认配置下可以很好地处理所有这些问题。

Hi Roman,所以当我添加该方法时,我会得到一个登录弹出窗口,而不是我的自定义登录页面,即使我尝试访问“/login”路由。现在它返回到仅显示:此页面不工作。localhost将您重定向了太多次。请尝试清除您的Cookie。ERR_TOO_MANY_redirects Hanks,Roman,我确认需要将登录URL添加到许可匹配器。在我的例子中,.antMatchers(“.css”、“.js”、“/pages/login/”).permitAll()“Hi Roman,所以当我添加该方法时,我会得到一个登录弹出窗口,而不是我的自定义登录页面,即使当我尝试访问“/login”路由时也是如此。现在,它又回到了仅显示:此页面不起作用。localhost将您重定向了太多次。请尝试清除您的cookie。ERR_TOO_MANY_redirects Hanks,Roman,我确认需要将登录URL添加到许可匹配器。在我的例子中,.antMatchers(“.css”、“.js”、“/pages/login/”.permitAll()”Hi-LGALAZI,因此堆栈跟踪中没有错误,只有一组hibernate控制台输出。当我运行调试器时,我看到它返回一个匿名用户,并抛出username not found异常,该异常通过重定向到登录页面来处理,我认为这是可以的。但是,我不明白的是,为什么登录页面根本没有呈现出来。因为您有一个异常处理程序,当抛出UserNotFoundException时,它会重定向到登录页面。因此,您加载登录页面,它查找用户,但没有找到,抛出异常,重定向到登录。一次又一次。这就是为什么您的浏览器出现“重定向太多”错误。您的UserHandler根本不允许匿名访问。如果你不允许匿名访问,没有人能够访问登录页面并进行身份验证。您应该删除该类,并让SecurityConfig类中的配置为您解决该问题。啊,这就解决了它!谢谢@lgalazzi!嗨,lgaleazzi,所以堆栈跟踪中没有错误,只有一堆hibernate控制台输出。当我运行调试器时,我看到它返回一个匿名用户,并抛出username not found异常,该异常通过重定向到登录页面来处理,我认为这是可以的。但是,我不明白的是,为什么登录页面根本没有呈现出来。因为您有一个异常处理程序,当抛出UserNotFoundException时,它会重定向到登录页面。因此,您加载登录页面,它查找用户,但没有找到,抛出异常,重定向到登录。一次又一次。这就是为什么您的浏览器出现“重定向太多”错误。您的UserHandler根本不允许匿名访问。如果你不允许匿名访问,没有人能够访问登录页面并进行身份验证。您应该删除该类,并让SecurityConfig类中的配置为您解决该问题。啊,这就解决了它!谢谢@lgalazzi!