RBAC权限控制
为了方便理解引用一个例子:图书馆借书系统。
1. 定义权限注解(相当于工作证)
// 这就像给不同岗位发的工作证
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresPermissions {String[] value(); // 需要的权限
}
2. 权限切面(相当于门卫)
@Aspect
@Component
public class LibraryGuard {// 当前用户的权限(模拟)private Set<String> currentUserPermissions = new HashSet<>();/*** 检查进入某个区域是否需要特定权限* 就像图书馆不同区域的门卫*/@Before("@annotation(workCard)")public void checkAccess(JoinPoint joinPoint, RequiresPermissions workCard) {String[] neededPermissions = workCard.value();System.out.println("门卫:检查进入 " + getMethodName(joinPoint) + " 区域");System.out.println("需要的权限:" + Arrays.toString(neededPermissions));System.out.println("您拥有的权限:" + currentUserPermissions);// 检查每个需要的权限for (String permission : neededPermissions) {if (!currentUserPermissions.contains(permission)) {System.out.println("❌ 权限不足!缺少:" + permission);throw new SecurityException("对不起,您没有权限进入这个区域");}}System.out.println("✅ 权限检查通过,欢迎进入!");}// 设置当前用户权限(模拟登录)public void login(String role) {currentUserPermissions.clear();switch (role) {case "admin":currentUserPermissions.addAll(Arrays.asList("book:manage", "book:borrow", "book:view", "user:manage"));System.out.println("👑 管理员登录成功");break;case "staff":currentUserPermissions.addAll(Arrays.asList("book:borrow", "book:view"));System.out.println("👔 借阅员登录成功");break;case "reader":currentUserPermissions.add("book:view");System.out.println("👤 读者登录成功");break;}System.out.println("您的权限:" + currentUserPermissions);}private String getMethodName(JoinPoint joinPoint) {return joinPoint.getSignature().getName();}
}
3. 图书馆服务(不同的功能区域)
@Service
public class LibraryService {// 图书管理区 - 需要管理员权限@RequiresPermissions({"book:manage"})public void addNewBook(String bookName) {System.out.println("📚 成功添加新书:" + bookName);}// 借书还书区 - 需要借阅权限@RequiresPermissions({"book:borrow"})public void borrowBook(String bookName, String userName) {System.out.println("📖 " + userName + " 成功借阅:" + bookName);}// 图书查询区 - 只需要查看权限@RequiresPermissions({"book:view"})public void searchBook(String keyword) {System.out.println("🔍 搜索图书:" + keyword);}// 用户管理区 - 需要用户管理权限@RequiresPermissions({"user:manage"})public void manageUsers() {System.out.println("👥 进入用户管理后台");}
}
4. 测试运行
@SpringBootTest
public class LibraryTest {@Autowiredprivate LibraryGuard libraryGuard;@Autowiredprivate LibraryService libraryService;@Testpublic void testDifferentUsers() {System.out.println("=== 测试不同用户的权限 ===");// 测试读者System.out.println("\n--- 读者尝试 ---");libraryGuard.login("reader");try {libraryService.searchBook("Java编程"); // ✅ 应该成功libraryService.borrowBook("Java编程", "张三"); // ❌ 应该失败} catch (SecurityException e) {System.out.println(e.getMessage());}// 测试借阅员System.out.println("\n--- 借阅员尝试 ---");libraryGuard.login("staff");try {libraryService.borrowBook("Python入门", "李四"); // ✅ 应该成功libraryService.addNewBook("新书"); // ❌ 应该失败} catch (SecurityException e) {System.out.println(e.getMessage());}// 测试管理员System.out.println("\n--- 管理员尝试 ---");libraryGuard.login("admin");try {libraryService.addNewBook("高级算法"); // ✅ 应该成功libraryService.manageUsers(); // ✅ 应该成功libraryService.borrowBook("数据结构", "王五"); // ✅ 应该成功} catch (SecurityException e) {System.out.println(e.getMessage());}}
}
运行结果示例
=== 测试不同用户的权限 ===--- 读者尝试 ---
👤 读者登录成功
您的权限:[book:view]
门卫:检查进入 searchBook 区域
需要的权限:[book:view]
您拥有的权限:[book:view]
✅ 权限检查通过,欢迎进入!
🔍 搜索图书:Java编程
门卫:检查进入 borrowBook 区域
需要的权限:[book:borrow]
您拥有的权限:[book:view]
❌ 权限不足!缺少:book:borrow
对不起,您没有权限进入这个区域--- 借阅员尝试 ---
👔 借阅员登录成功
您的权限:[book:borrow, book:view]
门卫:检查进入 borrowBook 区域
需要的权限:[book:borrow]
您拥有的权限:[book:borrow, book:view]
✅ 权限检查通过,欢迎进入!
📖 李四 成功借阅:Python入门
门卫:检查进入 addNewBook 区域
需要的权限:[book:manage]
您拥有的权限:[book:borrow, book:view]
❌ 权限不足!缺少:book:manage
对不起,您没有权限进入这个区域--- 管理员尝试 ---
👑 管理员登录成功
您的权限:[book:manage, user:manage, book:borrow, book:view]
门卫:检查进入 addNewBook 区域
需要的权限:[book:manage]
您拥有的权限:[book:manage, user:manage, book:borrow, book:view]
✅ 权限检查通过,欢迎进入!
📚 成功添加新书:高级算法
门卫:检查进入 manageUsers 区域
需要的权限:[user:manage]
您拥有的权限:[book:manage, user:manage, book:borrow, book:view]
✅ 权限检查通过,欢迎进入!
👥 进入用户管理后台
门卫:检查进入 borrowBook 区域
需要的权限:[book:borrow]
您拥有的权限:[book:manage, user:manage, book:borrow, book:view]
✅ 权限检查通过,欢迎进入!
📖 王五 成功借阅:数据结构
核心概念对应
| 图书馆例子 | 原权限系统 |
| 门卫检查 | 权限切面 |
| 工作证 | @RequiresPermissions注解 |
| 不同区域 | 不同方法 |
| 岗位权限 | 用户角色权限 |
| 门卫拒绝进入 | 抛出ServiceException |
