怎么利用 AccessDeniedException 构建基于异常驱动的应用层细粒度权限控制体系

风涛姑娘_5825

风涛姑娘_5825

2026-05-18

593人浏览

原创

accessdeniedexception 是 spring security 的拒绝访问异常信号,用于解耦权限决策与业务代码,通过 @preauthorize+spel、自定义 permissionevaluator、差异化异常处理及动态 grantedauthority 缓存构建可测试、可配置、可追溯的细粒度权限体系。

accessdeniedexception 是 spring security 提供的标准拒绝访问异常,它本身不负责权限判断,而是作为权限校验失败后的统一信号。构建异常驱动的细粒度权限控制体系,关键在于将权限决策逻辑与业务代码解耦,并让 accessdeniedexception 成为触发拦截、审计、降级或自定义响应的“枢纽点”,而非简单抛出后由全局处理器吞掉。

用 @PreAuthorize + SpEL 实现方法级动态权限表达式

在 Service 方法上标注注解,把权限规则写成可读性强的表达式,避免硬编码 if-check。Spring Security 会在方法执行前自动解析 SpEL,调用 Authentication 和上下文对象完成校验:

  • 资源归属校验:@PreAuthorize("#order.userId == authentication.principal.id") —— 确保当前用户是订单所属人
  • 角色+属性组合:@PreAuthorize("hasRole('ADMIN') or (#doc.status == 'DRAFT' and #doc.ownerId == authentication.principal.id)")
  • 委托调用支持:配合 @EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true) 启用代理

自定义 PermissionEvaluator 实现领域模型感知的权限判定

当 SpEL 表达式无法覆盖复杂业务逻辑(如审批链、部门树、租户隔离)时,应实现 PermissionEvaluator 接口,把权限判断下沉到领域层:

  • 在 supports() 中识别自定义权限类型(如 "CAN_EDIT_PROJECT")
  • 在 hasPermission() 中注入 Repository 或 DomainService,查库/调用领域规则(例如:“用户是否在项目成员列表中且角色非只读”)
  • 在 @PreAuthorize 中直接使用:@PreAuthorize("hasPermission(#project, 'CAN_EDIT_PROJECT')")

捕获 AccessDeniedException 做差异化响应与可观测增强

不要只靠 @ControllerAdvice 全局返回 403。应在关键入口(如 API 网关、聚合服务、前端 BFF 层)主动捕获并区分处理:

Web Accessibility (WCAG 2 AA))
Web Accessibility (WCAG 2 AA))

将 WCAG 2 AA 无障碍标准应用于设计系统、UI 组件和网页——通过可运行的验证器进行对比度计算,采用设计 token 模式使颜色天生可访问,设定排版和焦点状态规则,并提供语义检查清单。适用于构建或审查 UI。

下载
  • 前端友好提示:根据异常 cause 或嵌套 exception 类型,返回不同 message(如 “您无权编辑他人草稿” vs “该功能暂未向您的角色开放”)
  • 审计日志强化:记录被拒资源 ID、操作类型、用户身份、请求路径、时间戳,便于后续分析越权尝试模式
  • 熔断/降级联动:对高频拒绝的接口路径做统计,触发告警或临时限制非核心权限请求频次

结合 GrantedAuthority 动态构造与缓存提升性能

细粒度权限若每次请求都实时计算,容易成为瓶颈。应将权限元数据预加载并结构化:

  • 登录时从 DB 或配置中心拉取用户全部有效权限(如 PROJECT_123:EDIT、TENANT_A:MANAGE_USERS),封装为 CustomGrantedAuthority 对象
  • 重写 UserDetailsService 的 loadUserByUsername,把权限集合注入 Authentication
  • 对高频变更权限(如角色调整),通过 Redis Pub/Sub 通知各节点刷新 Authority 缓存,避免 Session 重启

这套体系不是靠异常本身做控制,而是以 AccessDeniedException 为统一出口,倒逼权限逻辑前置、可配置、可追溯。它让权限成为可测试的领域能力,而不是散落在 if 语句里的魔法字符串。

相关文章

驱动精灵
驱动精灵

驱动精灵基于驱动之家十余年的专业数据积累,驱动支持度高,已经为数亿用户解决了各种电脑驱动问题、系统故障,是目前有效的驱动软件,有需要的小伙伴快来保存下载体验吧!

下载

相关标签:

access

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

11177

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

8302

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

7172

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1204

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

968

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1436

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2949

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20211

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1295

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SQL 教程
SQL 教程

共61课时 | 7.4万人学习