RBAC通过“用户—角色—权限”三层解耦实现灵活授权:用户归属角色,权限绑定角色,校验时判断角色是否具备权限;需5张表(user、role、permission、user_role、role_permission);permission表应含code和name字段,role表可加type区分角色类型;Spring Security中通过自定义UserDetailsService加载权限字符串并封装为GrantedAuthority,配合@PreAuthorize注解实现方法级鉴权;动态权限更新应基于Redis缓存角色权限关系,并在变更时清除对应缓存,避免本地缓存导致集群不一致。

理解RBAC核心概念,避免设计跑偏
RBAC(Role-Based Access Control)不是简单地给用户打标签,而是通过“用户—角色—权限”三层解耦实现灵活授权。关键点在于:用户不直接关联权限,而是归属一个或多个角色;权限只绑定到角色上;系统校验时只判断当前用户拥有的角色是否具备该操作所需权限。这样,新增功能只需配置新权限+分配到对应角色,无需修改用户数据。
数据库表结构设计要点
最少需5张表支撑基础RBAC:user(用户)、role(角色)、permission(权限)、user_role(用户-角色中间表)、role_permission(角色-权限中间表)。注意:permission表建议包含字段code(如user:delete、order:export)和name(中文描述),便于前端展示与后端鉴权匹配;role表可加type字段区分系统角色(如ADMIN)与业务角色(如SALES_MANAGER),方便分级管理。
Spring Security整合RBAC的实用做法
用Spring Security实现时,重点在自定义UserDetailsService和权限表达式。在loadUserByUsername中查出用户、其角色及对应的所有权限字符串(如["user:list", "user:detail"]),封装进GrantedAuthority集合返回。配置类中使用@PreAuthorize("hasAuthority('user:delete')")即可控制方法级访问,无需手写if判断。接口权限校验统一走Filter或全局异常处理器,捕获AccessDeniedException返回403提示。
动态权限更新与缓存处理
权限变更(如管理员调整角色权限)不应重启服务。推荐方案:将角色-权限关系加载到Redis中,Key为role:permissions:{roleId},值为权限code集合;用户登录时把其角色ID列表存入Redis,再拼接获取全部权限缓存。当权限变更时,主动清除相关role和user的缓存Key。避免用本地缓存(如Caffeine),否则集群环境下各节点权限状态不一致。
立即学习“Java免费学习笔记(深入)”;










