权限校验最佳实践模型讲解
一、整体架构
二、核心组件详解
1. 请求处理流程
2. SecurityContext 工作原理
关键点:
- 每个线程独立存储用户信息
- 请求结束后必须清理,防止线程复用导致数据泄露
afterCompletion总会被调用(即使发生异常)
3. 匿名URL配置原理
4. 权限校验逻辑
三、三种权限校验方式对比
| 方式 | 位置 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| @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")) {
// 显示添加按钮
}
}
四、数据级权限校验
五、注意事项
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-权限校验最佳实践模型-快捷使用清单
💬 评论