简易权限切面用Set预载白名单权限标识(如read:config),通过AOP拦截标注@RequireFilePermission的方法,在执行前校验权限是否在ALLOWED_FILE_PERMS中,不满足则抛异常;所有受控文件访问须经封装层,禁用直接IO调用。

在简易权限切面中,用 Set 管理白名单 + 文件读取拦截未认证访问,关键不是“先校验再读”,而是把权限判断逻辑前置到文件操作触发前,并通过 Set 快速比对。不需要引入 Spring Security 或完整 RBAC 模型,几行核心代码就能落地。
用 Set 预载白名单权限并统一校验入口
把允许访问文件资源的权限标识(如 read:config、view:log)预先加载进一个全局或线程级的 Set<String>。这个 Set 可从配置文件(如 JSON、properties)读取,启动时初始化一次即可:
- 读取
whitelist-perms.json:内容为["read:config", "view:log", "download:report"] - 解析后存入静态 final Set:
public static final Set<String> ALLOWED_FILE_PERMS = new HashSet<>(Arrays.asList(...)) - 避免每次拦截都 IO 读文件——只在应用启动或热更新时重载
在 AOP 切点中拦截文件操作方法
针对典型文件读取行为(如 FileReader.read()、Files.readString()、自定义的 ResourceService.loadConfig()),用 @Around 切面包裹。重点不是拦截所有 IO,而是拦截你明确标记为“需鉴权”的业务方法:
- 定义注解
@RequireFilePermission("read:config"),标注在方法上 - 切面提取该注解值,转成字符串,检查是否在
ALLOWED_FILE_PERMS中 - 不满足直接抛
AccessDeniedException,不执行后续文件读取逻辑
绕过反射/底层调用的注意事项
纯 AOP 对 new FileInputStream(...) 或 FileChannel.map() 这类直接 API 调用无效——它们不经过 Spring 代理也不触发切点。所以必须约定:
- 所有受控文件访问必须走封装层(如
SecureFileReader工具类或 Service 方法) - 禁止在 Controller 或 Service 内直接 new File / Files / Paths —— 这是规范红线
- 若必须支持底层访问,可配合 SecurityManager(已弃用)或 JVM Agent,但简易场景不推荐
权限与路径联动(轻量增强)
如果不同路径对应不同权限(如 /conf/app.yml → read:config,/logs/error.log → view:log),可在切面中解析目标路径,动态查表匹配所需权限:
- 维护一个
Map<Pattern, String> pathToPerm = Map.of(Pattern.compile("/conf/.*"), "read:config") - 从 JoinPoint 获取参数中的文件路径,匹配 Pattern,取出对应权限字符串
- 再用该字符串去查
ALLOWED_FILE_PERMSSet,完成最终判定

















