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

无法自定义AccessDeniedException的问题求助

解决Spring Security AccessDeniedException自定义处理不生效问题

为什么@RestControllerAdvice无法捕获AccessDeniedException

Spring Security的过滤器链执行顺序早于DispatcherServlet,当权限校验失败抛出AccessDeniedException时,会被Security内置的ExceptionTranslationFilter直接捕获处理,不会将异常传递到DispatcherServlet层面,因此@RestControllerAdvice定义的全局异常处理器无法感知到这个异常。

正确配置CustomAccessDeniedHandler的步骤

1. 实现自定义AccessDeniedHandler

创建自定义处理器类,实现AccessDeniedHandler接口,重写handle方法返回自定义响应:

@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
        // 设置响应状态码为403
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.setContentType("application/json;charset=UTF-8");
        // 自定义JSON响应体
        String responseBody = "{\"code\": 403, \"msg\": \"您没有权限访问该资源\", \"detail\": \"" + accessDeniedException.getMessage() + "\"}";
        response.getWriter().write(responseBody);
    }
}

2. 在SecurityFilterChain中注册自定义处理器

确保在Security配置类中通过exceptionHandling()方法配置自定义处理器,注意配置顺序:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final CustomAccessDeniedHandler customAccessDeniedHandler;

    // 构造注入自定义处理器
    public SecurityConfig(CustomAccessDeniedHandler customAccessDeniedHandler) {
        this.customAccessDeniedHandler = customAccessDeniedHandler;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // 配置权限规则
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            )
            // 配置异常处理,指定自定义AccessDeniedHandler
            .exceptionHandling(exceptions -> exceptions
                .accessDeniedHandler(customAccessDeniedHandler)
            )
            // 其他Security配置(如登录、退出等)根据实际需求添加
            .formLogin(form -> form.loginPage("/login").permitAll());

        return http.build();
    }
}

排查CustomAccessDeniedHandler不生效的常见问题

  • 未将处理器注册为Spring Bean:确保自定义处理器类添加了@Component注解,或者在配置类中通过@Bean方法注册。
  • Security配置顺序错误:如果存在多个SecurityFilterChain配置,需确保当前配置的优先级更高(可通过@Order注解指定顺序)。
  • 其他过滤器拦截了异常:检查是否有自定义过滤器提前捕获了异常,导致ExceptionTranslationFilter无法处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:47:41