Spring Boot HttpSecurity异常处理问题:无法跳转自定义403页面
修复Spring Security accessDeniedPage导致StackOverflowError的问题
问题根源
你遇到的栈溢出是因为自定义403页面的路径/error/403没有被Spring Security放行。当用户触发权限拒绝时,系统尝试跳转到/error/403,但Spring Security会对这个路径再次进行权限校验,由于未放行,又触发权限拒绝,形成无限循环,最终导致StackOverflowError。
修复方案
方案1:放行403页面路径
在authorizeHttpRequests中添加对/error/403的放行配置,让所有用户都能访问该页面:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { return http .exceptionHandling(excHand -> excHand.accessDeniedPage("/error/403")) .csrf(csrfCustomizer->csrfCustomizer.disable()) .authorizeHttpRequests(auth -> auth .requestMatchers("/error/403").permitAll() // 新增放行配置 .requestMatchers("/").hasAnyRole("USER") ) .formLogin(formLogin -> formLogin .loginPage("/login") .permitAll() ) .logout(logout -> logout.logoutUrl("/logout") .permitAll() ) .build(); }
方案2:使用自定义AccessDeniedHandler替代accessDeniedPage
如果需要更灵活的权限拒绝处理逻辑,可以直接实现AccessDeniedHandler接口,避免路径跳转可能带来的循环问题:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { return http .exceptionHandling(excHand -> excHand.accessDeniedHandler((request, response, accessDeniedException) -> { // 设置响应状态码为403 response.setStatus(HttpServletResponse.SC_FORBIDDEN); // 转发到自定义403页面(或直接返回JSON) request.getRequestDispatcher("/error/403").forward(request, response); })) .csrf(csrfCustomizer->csrfCustomizer.disable()) .authorizeHttpRequests(auth -> auth .requestMatchers("/error/403").permitAll() // 同样需要放行该路径 .requestMatchers("/").hasAnyRole("USER") ) .formLogin(formLogin -> formLogin .loginPage("/login") .permitAll() ) .logout(logout -> logout.logoutUrl("/logout") .permitAll() ) .build(); }
额外验证点
- 确保
/error/403路径对应的控制器或静态页面确实存在,比如:@Controller public class ErrorController { @GetMapping("/error/403") public String accessDenied() { return "error/403"; // 对应templates下的error/403.html(如果用Thymeleaf) } }
内容的提问来源于stack exchange,提问作者Fabrizio Aliente
相关产品推荐
相关产品推荐

