You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
431 lines
22 KiB
431 lines
22 KiB
|
1 month ago
|
# 授权模型
|
||
|
|
|
||
|
|
<cite>
|
||
|
|
**本文引用的文件**
|
||
|
|
- [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java)
|
||
|
|
- [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java)
|
||
|
|
- [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java)
|
||
|
|
- [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java)
|
||
|
|
- [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java)
|
||
|
|
- [ISysMenuService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysMenuService.java)
|
||
|
|
- [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java)
|
||
|
|
- [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java)
|
||
|
|
- [MenuTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuTypeEnum.java)
|
||
|
|
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
|
||
|
|
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
|
||
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
||
|
|
- [AuthLoginUser.java](file://crm-auth/src/main/java/com/crm/auth/security/AuthLoginUser.java)
|
||
|
|
- [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java)
|
||
|
|
- [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java)
|
||
|
|
- [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java)
|
||
|
|
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
|
||
|
|
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
|
||
|
|
- [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java)
|
||
|
|
- [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java)
|
||
|
|
- [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java)
|
||
|
|
- [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java)
|
||
|
|
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
|
||
|
|
- [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java)
|
||
|
|
- [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java)
|
||
|
|
</cite>
|
||
|
|
|
||
|
|
## 目录
|
||
|
|
1. [简介](#简介)
|
||
|
|
2. [项目结构](#项目结构)
|
||
|
|
3. [核心组件](#核心组件)
|
||
|
|
4. [架构总览](#架构总览)
|
||
|
|
5. [详细组件分析](#详细组件分析)
|
||
|
|
6. [依赖关系分析](#依赖关系分析)
|
||
|
|
7. [性能考虑](#性能考虑)
|
||
|
|
8. [故障排查指南](#故障排查指南)
|
||
|
|
9. [结论](#结论)
|
||
|
|
10. [附录](#附录)
|
||
|
|
|
||
|
|
## 简介
|
||
|
|
本文件面向CRM系统的RBAC权限模型,围绕“角色-菜单-用户”三层权限架构进行系统化说明。重点覆盖:
|
||
|
|
- 实体与表结构设计:SysRole(角色)、SysMenu(菜单)、SysUserRole(用户-角色关联)以及SysRoleMenu(角色-菜单关联)
|
||
|
|
- 权限服务实现:PermissionServiceImpl的权限校验、菜单树获取、按钮级权限控制
|
||
|
|
- 权限继承与数据权限范围:基于枚举的数据范围控制与拦截器注入
|
||
|
|
- 动态权限加载:登录成功后从数据库加载并缓存到上下文
|
||
|
|
- 使用示例:Controller层注解声明与调用流程
|
||
|
|
|
||
|
|
## 项目结构
|
||
|
|
本项目采用多模块组织,权限相关代码集中在认证授权模块crm-auth中,通用能力在crm-base中提供。关键路径如下:
|
||
|
|
- 领域实体与枚举:crm-auth/domain/entity, crm-auth/domain/enums
|
||
|
|
- 安全配置与过滤器:crm-auth/config, crm-auth/security
|
||
|
|
- 服务实现:crm-auth/service/impl
|
||
|
|
- 基础能力:crm-base/security, crm-base/annotation, crm-base/domain
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
graph TB
|
||
|
|
subgraph "认证授权模块(crm-auth)"
|
||
|
|
A["实体: SysRole/SysMenu/SysUserRole/SysRoleMenu"]
|
||
|
|
B["枚举: DataScopeEnum/MenuTypeEnum"]
|
||
|
|
C["服务: PermissionServiceImpl/SysMenuServiceImpl"]
|
||
|
|
D["安全: SecurityConfig/JwtAuthenticationFilter/TokenService"]
|
||
|
|
E["数据权限: DataScopeInterceptor/DataScopeTables"]
|
||
|
|
end
|
||
|
|
subgraph "基础模块(crm-base)"
|
||
|
|
F["注解: @DataScope"]
|
||
|
|
G["工具: DataScopeHelper/DataVisibilityContext/SecurityUtils"]
|
||
|
|
H["实体基类: BaseEntity/OwnedEntity"]
|
||
|
|
I["异常与结果: ResultCodeEnum/BusinessErrorException/PermissionErrorException"]
|
||
|
|
end
|
||
|
|
A --> C
|
||
|
|
B --> C
|
||
|
|
D --> C
|
||
|
|
E --> C
|
||
|
|
F --> E
|
||
|
|
G --> E
|
||
|
|
H --> A
|
||
|
|
I --> C
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java)
|
||
|
|
- [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java)
|
||
|
|
- [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java)
|
||
|
|
- [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java)
|
||
|
|
- [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java)
|
||
|
|
- [MenuTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuTypeEnum.java)
|
||
|
|
- [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java)
|
||
|
|
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
|
||
|
|
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
|
||
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
||
|
|
- [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java)
|
||
|
|
- [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java)
|
||
|
|
- [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java)
|
||
|
|
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
|
||
|
|
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
|
||
|
|
- [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java)
|
||
|
|
- [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java)
|
||
|
|
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
|
||
|
|
- [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java)
|
||
|
|
- [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
|
||
|
|
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
|
||
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
||
|
|
|
||
|
|
## 核心组件
|
||
|
|
- 角色实体(SysRole):定义角色标识、名称、状态等元信息,作为权限集合的载体
|
||
|
|
- 菜单实体(SysMenu):定义菜单层级、类型(目录/菜单/按钮)、路由与权限标识,支撑前端菜单渲染与按钮显隐
|
||
|
|
- 用户角色关联(SysUserRole):将用户与角色建立多对多关系,承载用户的角色集合
|
||
|
|
- 角色菜单关联(SysRoleMenu):将角色与菜单建立多对多关系,承载角色的菜单与按钮权限集合
|
||
|
|
- 数据范围枚举(DataScopeEnum):定义数据可见范围(如全部、本部门、本人等),配合数据权限拦截器生效
|
||
|
|
- 菜单类型枚举(MenuTypeEnum):区分目录、菜单、按钮三类资源,用于权限判断与前端渲染
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java)
|
||
|
|
- [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java)
|
||
|
|
- [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java)
|
||
|
|
- [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java)
|
||
|
|
- [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java)
|
||
|
|
- [MenuTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuTypeEnum.java)
|
||
|
|
|
||
|
|
## 架构总览
|
||
|
|
下图展示了登录鉴权、权限加载、菜单渲染与数据权限控制的端到端流程。
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
sequenceDiagram
|
||
|
|
participant Client as "客户端"
|
||
|
|
participant Filter as "JwtAuthenticationFilter"
|
||
|
|
participant TokenSvc as "TokenService"
|
||
|
|
participant PermSvc as "PermissionServiceImpl"
|
||
|
|
participant MenuSvc as "SysMenuServiceImpl"
|
||
|
|
participant DB as "数据库"
|
||
|
|
participant Interceptor as "DataScopeInterceptor"
|
||
|
|
Client->>Filter : "携带JWT发起请求"
|
||
|
|
Filter->>TokenSvc : "解析并验证Token"
|
||
|
|
TokenSvc-->>Filter : "返回用户上下文"
|
||
|
|
Filter->>PermSvc : "加载用户权限(角色/菜单/按钮)"
|
||
|
|
PermSvc->>DB : "查询角色-菜单关联"
|
||
|
|
DB-->>PermSvc : "返回权限集合"
|
||
|
|
PermSvc-->>Filter : "写入当前用户权限上下文"
|
||
|
|
Client->>Interceptor : "访问受保护接口"
|
||
|
|
Interceptor->>DB : "根据@DataScope生成SQL条件"
|
||
|
|
DB-->>Interceptor : "返回受限数据集"
|
||
|
|
Interceptor-->>Client : "返回业务数据"
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
|
||
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
||
|
|
- [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java)
|
||
|
|
- [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java)
|
||
|
|
- [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java)
|
||
|
|
|
||
|
|
## 详细组件分析
|
||
|
|
|
||
|
|
### 实体与表结构设计
|
||
|
|
- SysRole(角色)
|
||
|
|
- 关键字段:角色ID、角色编码、角色名称、状态、排序等
|
||
|
|
- 作用:作为权限聚合的最小单元,多个角色可组合赋予用户
|
||
|
|
- SysMenu(菜单)
|
||
|
|
- 关键字段:菜单ID、父级ID、类型(目录/菜单/按钮)、路由、权限标识、图标、排序等
|
||
|
|
- 作用:构建菜单树,同时为按钮级权限提供唯一标识
|
||
|
|
- SysUserRole(用户-角色关联)
|
||
|
|
- 关键字段:用户ID、角色ID
|
||
|
|
- 作用:承载用户拥有的角色集合
|
||
|
|
- SysRoleMenu(角色-菜单关联)
|
||
|
|
- 关键字段:角色ID、菜单ID
|
||
|
|
- 作用:承载角色拥有的菜单与按钮权限集合
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
erDiagram
|
||
|
|
SYS_ROLE {
|
||
|
|
bigint id PK
|
||
|
|
string role_code UK
|
||
|
|
string role_name
|
||
|
|
int status
|
||
|
|
int sort_order
|
||
|
|
}
|
||
|
|
SYS_MENU {
|
||
|
|
bigint id PK
|
||
|
|
bigint parent_id
|
||
|
|
enum type
|
||
|
|
string path
|
||
|
|
string permission_code
|
||
|
|
string icon
|
||
|
|
int sort_order
|
||
|
|
}
|
||
|
|
SYS_USER_ROLE {
|
||
|
|
bigint user_id FK
|
||
|
|
bigint role_id FK
|
||
|
|
}
|
||
|
|
SYS_ROLE_MENU {
|
||
|
|
bigint role_id FK
|
||
|
|
bigint menu_id FK
|
||
|
|
}
|
||
|
|
SYS_ROLE ||--o{ SYS_ROLE_MENU : "拥有"
|
||
|
|
SYS_MENU ||--o{ SYS_ROLE_MENU : "被拥有"
|
||
|
|
SYS_USER ||--o{ SYS_USER_ROLE : "属于"
|
||
|
|
SYS_ROLE ||--o{ SYS_USER_ROLE : "分配给"
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java)
|
||
|
|
- [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java)
|
||
|
|
- [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java)
|
||
|
|
- [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java)
|
||
|
|
- [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java)
|
||
|
|
- [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java)
|
||
|
|
- [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java)
|
||
|
|
|
||
|
|
### 权限服务实现(PermissionServiceImpl)
|
||
|
|
- 权限校验逻辑
|
||
|
|
- 基于当前登录用户已加载的角色集合,结合角色-菜单关联,计算用户具备的菜单与按钮权限集合
|
||
|
|
- 支持按权限标识精确匹配,用于按钮级控制与接口级鉴权
|
||
|
|
- 菜单权限获取
|
||
|
|
- 通过菜单树结构组装,过滤出用户有权限的节点,形成前端可用的菜单树
|
||
|
|
- 支持按类型筛选(目录/菜单/按钮),便于不同场景展示
|
||
|
|
- 按钮级权限控制
|
||
|
|
- 以权限标识为核心,前端根据标识控制按钮显示/隐藏,后端在关键操作处进行二次校验
|
||
|
|
- 权限继承关系
|
||
|
|
- 若菜单存在父子关系,父级菜单的权限通常包含子级;具体策略由菜单类型与枚举共同决定
|
||
|
|
- 数据权限范围控制
|
||
|
|
- 结合DataScopeEnum与@DataScope注解,在查询时自动注入部门/本人等数据范围条件
|
||
|
|
- 动态权限加载机制
|
||
|
|
- 登录成功后,从数据库读取用户角色与菜单权限,写入当前用户上下文,后续请求复用
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
Start(["进入权限校验"]) --> LoadUser["加载当前用户上下文"]
|
||
|
|
LoadUser --> HasRoles{"是否拥有角色?"}
|
||
|
|
HasRoles -- 否 --> Deny["拒绝访问"]
|
||
|
|
HasRoles -- 是 --> LoadMenus["加载角色-菜单关联"]
|
||
|
|
LoadMenus --> BuildPerms["构建权限集合(菜单/按钮)"]
|
||
|
|
BuildPerms --> CheckTarget{"目标权限是否存在?"}
|
||
|
|
CheckTarget -- 否 --> Deny
|
||
|
|
CheckTarget -- 是 --> ApplyScope["应用数据权限范围"]
|
||
|
|
ApplyScope --> Allow["允许访问"]
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java)
|
||
|
|
- [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java)
|
||
|
|
- [MenuTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuTypeEnum.java)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java)
|
||
|
|
- [ISysMenuService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysMenuService.java)
|
||
|
|
- [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java)
|
||
|
|
|
||
|
|
### 数据权限范围控制
|
||
|
|
- 注解驱动:在Mapper或Service方法上使用@DataScope,指定数据范围级别
|
||
|
|
- 拦截器注入:DataScopeInterceptor根据当前用户的数据范围,动态拼接SQL条件
|
||
|
|
- 范围类型:参考DataScopeEnum,常见包括全部、本部门、本人等
|
||
|
|
- 上下文传递:DataVisibilityContext保存当前可见范围,供查询阶段使用
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
sequenceDiagram
|
||
|
|
participant Controller as "控制器"
|
||
|
|
participant Mapper as "数据访问层"
|
||
|
|
participant Interceptor as "DataScopeInterceptor"
|
||
|
|
participant Context as "DataVisibilityContext"
|
||
|
|
participant DB as "数据库"
|
||
|
|
Controller->>Mapper : "调用带@DataScope的方法"
|
||
|
|
Mapper->>Interceptor : "触发数据权限拦截"
|
||
|
|
Interceptor->>Context : "读取当前用户数据范围"
|
||
|
|
Context-->>Interceptor : "返回范围参数"
|
||
|
|
Interceptor->>DB : "注入WHERE条件执行查询"
|
||
|
|
DB-->>Controller : "返回受限数据集"
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java)
|
||
|
|
- [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java)
|
||
|
|
- [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java)
|
||
|
|
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java)
|
||
|
|
- [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java)
|
||
|
|
- [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java)
|
||
|
|
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
|
||
|
|
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
|
||
|
|
|
||
|
|
### 动态权限加载机制
|
||
|
|
- 登录成功后,TokenService解析用户身份并加载角色
|
||
|
|
- PermissionServiceImpl根据角色集合查询菜单与按钮权限,构建权限集合
|
||
|
|
- 权限集合写入当前用户上下文,后续请求无需重复查询
|
||
|
|
- 前端根据权限集合渲染菜单与按钮
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
sequenceDiagram
|
||
|
|
participant Auth as "认证入口"
|
||
|
|
participant Token as "TokenService"
|
||
|
|
participant Perm as "PermissionServiceImpl"
|
||
|
|
participant DB as "数据库"
|
||
|
|
participant Ctx as "用户上下文"
|
||
|
|
Auth->>Token : "验证Token并获取用户信息"
|
||
|
|
Token-->>Auth : "返回用户基本信息"
|
||
|
|
Auth->>Perm : "加载用户权限"
|
||
|
|
Perm->>DB : "查询角色-菜单关联"
|
||
|
|
DB-->>Perm : "返回权限集合"
|
||
|
|
Perm->>Ctx : "写入权限集合"
|
||
|
|
Ctx-->>Auth : "权限可用"
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
||
|
|
- [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java)
|
||
|
|
- [AuthLoginUser.java](file://crm-auth/src/main/java/com/crm/auth/security/AuthLoginUser.java)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
||
|
|
- [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java)
|
||
|
|
- [AuthLoginUser.java](file://crm-auth/src/main/java/com/crm/auth/security/AuthLoginUser.java)
|
||
|
|
|
||
|
|
### 在Controller层进行权限注解声明
|
||
|
|
- 接口级鉴权:在需要鉴权的Controller方法上声明权限标识,由安全框架进行校验
|
||
|
|
- 按钮级控制:前端根据权限标识控制按钮显示/隐藏;后端在关键业务点再次校验
|
||
|
|
- 数据权限:在数据访问层方法上使用@DataScope,限定数据可见范围
|
||
|
|
|
||
|
|
使用建议:
|
||
|
|
- 权限标识应遵循统一命名规范,确保前后端一致
|
||
|
|
- 敏感操作需在后端进行二次校验,避免仅依赖前端控制
|
||
|
|
- 数据权限应与业务实体字段对齐,保证查询条件正确注入
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
|
||
|
|
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
|
||
|
|
- [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java)
|
||
|
|
|
||
|
|
## 依赖关系分析
|
||
|
|
- 权限服务依赖菜单服务与实体映射,用于构建权限集合与菜单树
|
||
|
|
- 安全过滤器依赖Token服务与权限服务,完成鉴权与权限加载
|
||
|
|
- 数据权限拦截器依赖上下文与注解,动态注入查询条件
|
||
|
|
- 基础模块提供通用实体基类、异常与结果封装
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
classDiagram
|
||
|
|
class PermissionServiceImpl {
|
||
|
|
+校验权限()
|
||
|
|
+获取菜单树()
|
||
|
|
+按钮级权限检查()
|
||
|
|
}
|
||
|
|
class SysMenuServiceImpl {
|
||
|
|
+构建菜单树()
|
||
|
|
+按类型过滤()
|
||
|
|
}
|
||
|
|
class DataScopeInterceptor {
|
||
|
|
+注入数据范围()
|
||
|
|
+处理注解()
|
||
|
|
}
|
||
|
|
class TokenService {
|
||
|
|
+解析Token()
|
||
|
|
+加载用户角色()
|
||
|
|
}
|
||
|
|
class JwtAuthenticationFilter {
|
||
|
|
+鉴权()
|
||
|
|
+加载权限()
|
||
|
|
}
|
||
|
|
PermissionServiceImpl --> SysMenuServiceImpl : "依赖"
|
||
|
|
JwtAuthenticationFilter --> TokenService : "依赖"
|
||
|
|
JwtAuthenticationFilter --> PermissionServiceImpl : "依赖"
|
||
|
|
DataScopeInterceptor --> PermissionServiceImpl : "读取权限上下文"
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java)
|
||
|
|
- [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java)
|
||
|
|
- [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java)
|
||
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
||
|
|
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java)
|
||
|
|
- [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java)
|
||
|
|
- [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java)
|
||
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
||
|
|
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
|
||
|
|
|
||
|
|
## 性能考虑
|
||
|
|
- 权限集合缓存:登录成功后将权限集合写入上下文,避免重复查询
|
||
|
|
- 菜单树构建优化:按需加载与缓存,减少前端渲染压力
|
||
|
|
- 数据权限注入:在拦截器层面一次性注入条件,避免多次拼接
|
||
|
|
- 索引设计:角色-菜单、用户-角色关联表建议建立复合索引以提升查询效率
|
||
|
|
|
||
|
|
[本节为通用指导,不直接分析具体文件]
|
||
|
|
|
||
|
|
## 故障排查指南
|
||
|
|
- 权限校验失败
|
||
|
|
- 检查用户是否分配了有效角色
|
||
|
|
- 确认角色-菜单关联是否正确
|
||
|
|
- 核对权限标识命名是否与前后端一致
|
||
|
|
- 菜单渲染异常
|
||
|
|
- 检查菜单类型与层级关系
|
||
|
|
- 确认权限过滤逻辑是否正确
|
||
|
|
- 数据权限不生效
|
||
|
|
- 检查@DataScope注解是否正确使用
|
||
|
|
- 确认数据范围枚举与上下文设置
|
||
|
|
- 常见异常
|
||
|
|
- 业务异常:BusinessErrorException
|
||
|
|
- 权限异常:PermissionErrorException
|
||
|
|
- 错误码:ResultCodeEnum
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java)
|
||
|
|
- [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java)
|
||
|
|
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
|
||
|
|
|
||
|
|
## 结论
|
||
|
|
本RBAC权限模型通过角色-菜单-用户的三层架构,实现了灵活的权限控制与数据范围管理。PermissionServiceImpl作为核心服务,串联起鉴权、菜单渲染与按钮级控制;结合数据权限拦截器与上下文,实现了细粒度的数据可见性控制。建议在开发过程中严格遵循权限标识规范,并在关键业务点进行后端二次校验,以确保系统的安全性与一致性。
|
||
|
|
|
||
|
|
[本节为总结性内容,不直接分析具体文件]
|
||
|
|
|
||
|
|
## 附录
|
||
|
|
- 最佳实践
|
||
|
|
- 权限标识命名规范化,前后端保持一致
|
||
|
|
- 敏感操作必须后端校验,避免仅依赖前端控制
|
||
|
|
- 数据权限与业务实体字段对齐,确保查询条件准确
|
||
|
|
- 扩展建议
|
||
|
|
- 引入权限变更事件,及时刷新上下文缓存
|
||
|
|
- 增加权限审计日志,便于问题追踪与分析
|
||
|
|
|
||
|
|
[本节为补充内容,不直接分析具体文件]
|