权限管理API
引用文件
目录
简介
本文件面向权限管理API,覆盖以下能力:
- 权限查询接口:用户权限获取、角色权限查询
- 角色管理接口:角色创建、更新、删除、查询
- 权限数据结构与角色权限映射关系
- 权限继承机制与数据权限范围
- 权限验证流程、角色分配示例与权限缓存策略
目标是帮助开发者快速理解并正确使用权限与角色相关接口,同时掌握底层实现原理与最佳实践。
项目结构
权限模块由“API接口层”“业务控制器层”“服务实现层”“数据对象层”组成,遵循分层与职责分离原则:
- API接口层:通过Feign声明远程RPC接口,供内部模块或网关调用
- 控制器层:暴露REST接口,进行鉴权与参数校验
- 服务实现层:封装权限与角色的核心逻辑,包括缓存、事务与数据权限处理
- 数据对象层:角色、用户-角色、角色-菜单等实体定义
图表来源
- PermissionApi.java
- RoleApi.java
- PermissionController.java
- RoleController.java
- PermissionServiceImpl.java
- RoleServiceImpl.java
- RoleDO.java
- UserRoleDO.java
- RoleMenuDO.java
章节来源
核心组件
- 权限API接口:提供用户-角色、角色-菜单、权限判断、数据权限查询等RPC接口
- 角色API接口:提供角色合法性校验RPC接口
- 权限控制器:提供REST接口,支持角色菜单分配、数据权限分配、用户角色分配与查询
- 角色控制器:提供REST接口,支持角色的增删改查、分页、导出、简易列表
- 权限服务实现:负责权限判断、角色-菜单/用户-角色映射、数据权限计算、缓存维护
- 角色服务实现:负责角色生命周期管理、数据范围更新、角色校验与缓存
章节来源
- PermissionApi.java
- RoleApi.java
- PermissionController.java
- RoleController.java
- PermissionServiceImpl.java
- RoleServiceImpl.java
架构总览
权限与角色相关请求在控制器层完成鉴权与参数校验后,进入服务层执行业务逻辑;服务层通过MyBatis访问数据库,同时利用Redis缓存提升查询性能;RPC接口通过Feign跨模块调用。
图表来源
详细组件分析
权限查询接口
- 用户权限获取
- RPC接口:根据用户ID获取其角色ID集合
- 控制器:提供REST接口,返回用户拥有的角色编号列表
- 角色权限查询
- RPC接口:根据角色ID集合获取拥有这些角色的用户ID集合
- 控制器:提供REST接口,返回角色拥有的菜单ID集合
- 权限判断
- RPC接口:判断用户是否拥有任一权限标识
- 控制器:提供REST接口,返回用户拥有的角色列表
- 数据权限
- RPC接口:获取登录用户的部门数据权限
- 控制器:提供REST接口,支持角色数据权限分配
章节来源
角色管理接口
- 创建角色:校验唯一性与类型,插入数据库并记录日志
- 更新角色:校验可更新性与唯一性,更新数据库并记录日志
- 删除角色:校验可删除性,标记删除并清理相关关联
- 查询角色:按ID、分页、状态、简易列表查询
- 导出角色:导出Excel
章节来源
权限数据结构与映射关系
- 角色表: 包含角色ID、名称、编码、排序、状态、类型、备注、数据范围及指定部门集合
- 用户-角色关联表:用户ID与角色ID的多对多映射
- 角色-菜单关联表:角色ID与菜单ID的多对多映射
图表来源
权限继承机制
- 超级管理员角色:当用户拥有超级管理员角色时,权限判断直接返回“拥有权限”
- 角色启用状态:仅启用状态的角色参与权限计算
- 菜单-权限映射:权限标识通过菜单表中的权限字段进行映射,未找到对应菜单则视为无权限
图表来源
数据权限范围
- ALL:可查看所有数据
- DEPT_ONLY:仅本人所在部门
- DEPT_AND_CHILD:所在部门及其子部门
- DEPT_CUSTOM:自定义部门集合(含自身部门)
- SELF:仅本人
图表来源
权限验证流程
- 控制器层使用Spring Security注解进行权限校验
- 服务层在执行角色-菜单、用户-角色变更时,清理相关Redis缓存以保证一致性
- 超级管理员角色在权限判断中具有最高优先级
章节来源
角色分配示例
- 分配用户角色
- 请求:POST /system/permission/assign-user-role
- 参数:userId、roleIds[]
- 流程:计算新增与删除的 角色,批量插入或删除用户-角色关联
- 分配角色菜单
- 请求:POST /system/permission/assign-role-menu
- 参数:roleId、menuIds[]
- 流程:清理菜单-角色缓存与权限-菜单缓存,计算差集并批量更新
- 分配角色数据权限
- 请求:POST /system/permission/assign-role-data-scope
- 参数:roleId、dataScope、dataScopeDeptIds[]
- 流程:更新角色的数据范围与指定部门集合
章节来源
权限缓存策略
- 用户-角色缓存:用户角色ID集合缓存,变更时按用户维度失效
- 菜单-角色缓存:菜单对应角色ID集合缓存,变更时按菜单维度失效
- 权限-菜单缓存:权限标识对应菜单ID集合缓存,变更时按权限维度失效
- 角色对象缓存:角色对象缓存,按角色ID维度失效
章节来源
依赖分析
- 控制器依赖服务:PermissionController与RoleController分别依赖PermissionServiceImpl与RoleServiceImpl
- 服务依赖DAO:PermissionServiceImpl与RoleServiceImpl依赖对应的Mapper与DO
- 缓存依赖:服务层通过RedisKeyConstants进行缓存键管理
- 枚举依赖:角色类型、数据范围等枚举影响业务逻辑
图表来源
- PermissionController.java
- RoleController.java
- PermissionServiceImpl.java
- RoleServiceImpl.java
- RoleDO.java
- UserRoleDO.java
- RoleMenuDO.java
性能考量
- 缓存命中率:通过Redis缓存用户-角色、菜单-角色、权限-菜单,降低数据库压力
- 批量操作:新增/删除用户-角色、角色-菜单时采用批量插入/删除,减少IO次数
- 惰性求值:用户部门ID通过Guava Suppliers惰性获取,避免不必要的DB查询
- 事务一致性:多数据源场景使用分布式事务注解,确保跨表更新一致性
故障排查指南
- 角色不存在或禁用:角色校验失败会抛出异常,需确认角色ID与状态
- 权限不足:检查用户是否拥有对应权限标识或是否为超级管理员
- 缓存不一致:角色或菜单变更后需清理相关缓存键,避免脏读
- 数据权限异常:核对角色数据范围配置与指定部门集合
章节来源
结论
本权限模块通过清晰的分层设计与完善的缓存策略,提供了高效稳定的权限与角色管理能力。权限判断遵循“启用角色+超级管理员优先”的规则,数据权限支持多种范围模型,满足复杂业务场景需求。建议在生产环境中重点关注缓存一致性与异常处理,确保权限系统的稳定与安全。
附录
- 角色类型枚举:内置角色与自定义角色区分
- 角色数据范围枚举:ALL、DEPT_ONLY、DEPT_AND_CHILD、DEPT_CUSTOM、SELF
章节来源