核心是运行时比对注解声明权限与用户权限并中断不匹配请求:定义@Target和@Retention的自定义注解,用@Aspect切面提取注解信息,从SecurityContext等获取用户权限,按requireAll策略校验后抛异常或放行。

核心在于将注解声明的权限要求,与当前用户所拥有的权限进行运行时比对,并在不匹配时中断请求流程。
定义自定义权限注解
用 @Target(ElementType.METHOD) 和 @Retention(RetentionPolicy.RUNTIME) 声明注解,支持在方法上标注所需权限标识(如角色名、操作码、资源类型等)。可设属性如 value()(字符串数组)、requireAll()(是否需全部满足)等,便于灵活表达权限策略。
编写拦截器或切面捕获注解信息
在 Spring 环境中,推荐使用 @Aspect 切面,在 @Around 通知中获取目标方法的注解实例。通过 joinPoint.getSignature() 定位到具体 Method 对象,再调用 method.getAnnotation(YourPermissionAnnotation.class) 提取配置。注意处理方法被代理(如 CGLIB)时的反射兼容性问题。
从上下文获取当前用户权限
通常从 SecurityContext(如 Spring Security 的 SecurityContextHolder.getContext().getAuthentication())中提取 principal 或 authorities。若未集成安全框架,也可从 ThreadLocal、RequestAttribute 或 JWT Token 解析中获取用户权限列表。确保权限数据结构能与注解中声明的值做有效比对(例如 Set.containsAll 或 Stream.anyMatch)。
执行校验并控制流程
根据注解配置和用户权限结果决定是否放行:
- 若 requireAll=true,检查用户权限是否包含注解中所有 value
- 若 requireAll=false(默认),检查是否存在至少一个匹配项
- 不通过时抛出统一异常(如 AccessDeniedException),由全局异常处理器返回 403 或自定义响应
- 通过则调用 proceed() 继续执行原方法
不复杂但容易忽略的是权限字符串的标准化——建议统一小写、去除空格、避免硬编码,配合枚举或配置中心管理权限标识,提升可维护性。

















