rbac权限管理模型的核心是建立“用户→角色→权限”三层间接关系,避免用户与权限直接绑定;通过5张表(user、role、permission、user_role、role_permission)建模,登录时加载权限至grantedauthority,结合@preauthorize或antmatchers实现接口级鉴权,并配套可视化角色权限管理界面确保可维护性。

RBAC权限管理模型的实现,核心是建立“用户→角色→权限”三层间接关系,避免用户与权限直接绑定。它不是靠硬编码判断身份,而是通过数据库建模 + 框架拦截 + 运行时校验来落地。关键不在于写多少代码,而在于结构是否清晰、扩展是否方便、权限是否可控。
数据库设计:5张表支撑基础关系
标准RBAC至少需要以下5张表,每张表职责明确,支持多对多关联:
- 用户表(sys_user):存用户名、密码(加密)、状态等基本信息,不存权限或角色
- 角色表(sys_role):存角色名称(如ROLE_ADMIN)、编码(如ADMIN)、描述
- 权限表(sys_permission):定义最小操作单元,格式建议为资源:动作,例如user:update、order:delete;可额外加字段标识类型(菜单/按钮/API)
- 用户角色关联表(sys_user_role):记录谁属于什么角色,字段为user_id和role_id
- 角色权限关联表(sys_role_permission):记录哪个角色拥有哪些权限,字段为role_id和permission_id
权限加载:登录时把权限注入SecurityContext
用户登录成功后,不能只查出用户名,必须查出他所有角色对应的所有权限,并构造成Spring Security能识别的GrantedAuthority对象集合。常见做法:
- 自定义UserDetailsService实现类,在loadUserByUsername方法中:根据用户名查用户 → 查用户角色 → 查每个角色的权限 → 封装成SimpleGrantedAuthority("ROLE_ADMIN")和SimpleGrantedAuthority("user:read")等
- 权限字符串统一加前缀(如ROLE_用于角色,无前缀用于细粒度权限),便于后续hasRole()或hasAuthority()区分使用
接口级权限控制:用注解或配置规则拦截请求
权限最终要作用到具体访问行为上。推荐两种方式结合使用:
-
URL路径控制(配置式):在HttpSecurity中用antMatchers限定路径所需角色或权限,例如:
.antMatchers("/api/users").hasAuthority("user:list")
.antMatchers("/admin/**").hasRole("ADMIN")(注意:hasRole("ADMIN")等价于hasAuthority("ROLE_ADMIN")) -
方法级控制(注解式):在Service或Controller方法上加@PreAuthorize,支持SpEL表达式,更灵活:
@PreAuthorize("hasAuthority('order:create') and #userId == authentication.principal.id")
可结合参数、当前用户信息做数据级校验(如“只能删自己的订单”)
角色与权限的维护:后台提供可视化管理能力
模型再好,如果运维无法修改,就只是纸上谈兵。需配套提供管理界面:
- 角色管理页:增删改查角色,支持为每个角色批量勾选权限
- 用户管理页:编辑用户时,可多选分配角色(不是直接配权限)
- 权限管理页:统一维护所有权限项,标注所属模块、是否启用、适用场景等元信息
- 关键逻辑:每次角色权限变更后,确保已登录用户的权限缓存及时失效(如清除SecurityContext或刷新token)











