spring boot 处理权限不足异常应聚焦 accessdeniedexception,优先使用 accessdeniedhandler 定制响应,其次用 @controlleradvice 拦截返回视图,或直接放置静态 403.html 实现自动渲染。

Spring Boot 中处理自定义权限不足异常,核心是把权限拒绝行为(如 AccessDeniedException)捕获并统一导向友好提示,而不是直接返回默认 403 页面或空白错误。关键不在于“抛出异常”,而在于“识别它、拦截它、响应它”。
明确权限异常的来源
权限不足通常由 Spring Security 主动抛出,最常见的是:
– AccessDeniedException:用户已认证,但无访问资源所需权限
– AuthenticationException 子类(如 BadCredentialsException):认证失败,属于登录环节问题,不属于“权限不足”范畴
因此,处理重点应放在 AccessDeniedException 及其子类上,而非泛泛捕获所有 Exception。
用 @ControllerAdvice 拦截并重定向到无权限页
适用于前后端分离不严格、仍使用 Thymeleaf/FreeMarker 或返回 HTML 视图的场景:
- 创建全局异常处理器类,标注
@ControllerAdvice(不是@RestControllerAdvice,因需返回视图) - 编写
@ExceptionHandler(AccessDeniedException.class)方法 - 方法返回字符串视图名(如
"error/403"),对应src/main/resources/templates/error/403.html或src/main/resources/static/error/403.html - 确保该页面存在且能被正确解析(Thymeleaf 项目推荐放 templates 下;纯静态页可放 static 下)
用 Spring Security 的 AccessDeniedHandler 定制跳转逻辑
这是更标准、更解耦的做法,专为权限拒绝设计,不依赖 Controller 层:
- 实现
AccessDeniedHandler接口,重写handle()方法 - 在方法中可做三件事:记录日志、设置响应状态码(如 403)、执行重定向(
response.sendRedirect("/unauthorized"))或转发(request.getRequestDispatcher("/error/403").forward(request, response)) - 将该 Bean 注册进 Security 配置,例如在
SecurityConfig中调用.exceptionHandling().accessDeniedHandler(yourHandler) - 优势:早于 Controller 执行,不受 MVC 异常处理器影响;适合纯 REST API + 前端路由的架构(重定向到前端 /unauthorized 路由)
补充:静态 403 页面自动生效机制
Spring Boot 内置错误处理支持约定式页面:
- 只要在
src/main/resources/static/error/(或templates/error/)下放置403.html - 无需任何 Java 代码,Spring Boot 默认会匹配 HTTP 状态码 403 并渲染该页面
- 注意:此方式对
AccessDeniedException有效,但前提是未配置自定义AccessDeniedHandler或全局异常处理器覆盖了它
不需要自己造轮子抛 CustomAccessDeniedException——直接利用 Spring Security 原生异常更稳妥。重点是选对拦截点:走 Security 的 AccessDeniedHandler 最规范,走 @ControllerAdvice 更灵活,放静态 403.html 最轻量。











