权限校验最佳实践模型讲解

一、整体架构

权限校验整体架构-45170a9f

二、核心组件详解

1. 请求处理流程

请求处理流程-2ee749ef

2. SecurityContext 工作原理

SecurityContext_工作原理-a9862ae7

关键点

  • 每个线程独立存储用户信息
  • 请求结束后必须清理,防止线程复用导致数据泄露
  • afterCompletion 总会被调用(即使发生异常)

3. 匿名URL配置原理

匿名URL配置原理-bc055e33

4. 权限校验逻辑

权限校验逻辑-9e9f55ee

三、三种权限校验方式对比

方式 位置 优点 缺点 适用场景
@RequiresPermission Controller方法 声明式、简洁、统一 灵活性较低 固定权限的接口
SecurityUtils.checkXxx() 代码任意位置 灵活、可动态判断 代码侵入性高 复杂权限逻辑
SecurityUtils.hasXxx() 代码任意位置 不抛异常、用于判断 需要自己处理逻辑 条件显示、动态菜单
// 方式1:注解声明式
@RequiresPermission("user:add")
@PostMapping("/user")
public Result addUser() { }

// 方式2:代码强制校验(失败抛异常)
public void addUser() {
    SecurityUtils.checkPermission("user:add");
    // 业务逻辑
}

// 方式3:代码条件判断(返回boolean)
public Result getMenu() {
    if (SecurityUtils.hasPermission("user:add")) {
        // 显示添加按钮
    }
}

四、数据级权限校验

数据级权限校验-0c54e9c4

五、注意事项

1. ThreadLocal 必须清理

// ❌ 错误:不清理会导致内存泄露和数据混乱
@Override
public boolean preHandle(...) {
    SecurityContext.setCurrentUser(user);
    return true;
}

// ✅ 正确:在 afterCompletion 中清理
@Override
public void afterCompletion(...) {
    SecurityContext.clear();  // 必须清理!
}

2. 静态方法注入问题

// SecurityUtils 是通过构造器注入初始化静态变量
@Component
public class SecurityUtils {
    private static PermissionHandler permissionHandler;

    // Spring 注入时初始化静态变量
    public SecurityUtils(PermissionHandler handler) {
        SecurityUtils.permissionHandler = handler;
    }
}

3. 优先级:方法注解 > 类注解

@RestController
@RequiresRole("user")  // 类级别:需要user角色
public class UserController {

    @GetMapping("/list")
    @RequiresRole("admin")  // 方法级别优先:需要admin角色
    public Result list() { }

    @GetMapping("/info")
    // 无方法注解,使用类级别:需要user角色
    public Result info() { }
}

项目分区导航:⬅️ 05-ZwwwSpringBootBaseTemplate工程模板 | 01-权限校验最佳实践模型讲解 | ➡️ 02-权限校验最佳实践模型-快捷使用清单