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.
523 lines
29 KiB
523 lines
29 KiB
|
1 month ago
|
# 权限管理系统
|
||
|
|
|
||
|
|
<cite>
|
||
|
|
**本文引用的文件**
|
||
|
|
- [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java)
|
||
|
|
- [application.yml](file://crm-app/src/main/resources/application.yml)
|
||
|
|
- [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java)
|
||
|
|
- [application.yml](file://crm-auth/src/main/resources/application.yml)
|
||
|
|
- [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java)
|
||
|
|
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
|
||
|
|
- [DataInitializer.java](file://crm-auth/src/main/java/com/crm/auth/config/DataInitializer.java)
|
||
|
|
- [AuthConstants.java](file://crm-auth/src/main/java/com/crm/auth/constant/AuthConstants.java)
|
||
|
|
- [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java)
|
||
|
|
- [SystemController.java](file://crm-auth/src/main/java/com/crm/auth/controller/SystemController.java)
|
||
|
|
- [AuthIdentity.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthIdentity.java)
|
||
|
|
- [AuthUser.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthUser.java)
|
||
|
|
- [SysDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java)
|
||
|
|
- [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java)
|
||
|
|
- [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java)
|
||
|
|
- [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java)
|
||
|
|
- [SysUserDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java)
|
||
|
|
- [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java)
|
||
|
|
- [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java)
|
||
|
|
- [IdentityTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/IdentityTypeEnum.java)
|
||
|
|
- [MenuTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuTypeEnum.java)
|
||
|
|
- [LoginParam.java](file://crm-auth/src/main/java/com/crm/auth/domain/param/LoginParam.java)
|
||
|
|
- [LoginResultDTO.java](file://crm-auth/src/main/java/com/crm/auth/domain/dto/LoginResultDTO.java)
|
||
|
|
- [UserInfoDTO.java](file://crm-auth/src/main/java/com/crm/auth/domain/dto/UserInfoDTO.java)
|
||
|
|
- [AuthIdentityMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/AuthIdentityMapper.java)
|
||
|
|
- [AuthUserMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/AuthUserMapper.java)
|
||
|
|
- [SysDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java)
|
||
|
|
- [SysMenuMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysMenuMapper.java)
|
||
|
|
- [SysRoleMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysRoleMapper.java)
|
||
|
|
- [SysRoleMenuMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysRoleMenuMapper.java)
|
||
|
|
- [SysUserDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserDeptMapper.java)
|
||
|
|
- [SysUserRoleMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserRoleMapper.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)
|
||
|
|
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
|
||
|
|
- [SecurityExceptionHandlers.java](file://crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.java)
|
||
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
||
|
|
- [DingTalkAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/DingTalkAuthClient.java)
|
||
|
|
- [ThirdPartyAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClient.java)
|
||
|
|
- [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java)
|
||
|
|
- [ThirdPartyUserInfo.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyUserInfo.java)
|
||
|
|
- [AuthIdentityServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthIdentityServiceImpl.java)
|
||
|
|
- [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java)
|
||
|
|
- [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java)
|
||
|
|
- [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java)
|
||
|
|
- [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java)
|
||
|
|
- [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java)
|
||
|
|
- [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java)
|
||
|
|
- [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)
|
||
|
|
- [IAuthIdentityService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthIdentityService.java)
|
||
|
|
- [IAuthService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java)
|
||
|
|
- [IAuthUserService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthUserService.java)
|
||
|
|
- [ISysDeptService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysDept.java)
|
||
|
|
- [ISysMenuService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysMenuService.java)
|
||
|
|
- [ISysRoleService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysRoleService.java)
|
||
|
|
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
|
||
|
|
- [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java)
|
||
|
|
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.java)
|
||
|
|
- [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java)
|
||
|
|
- [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java)
|
||
|
|
- [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.java)
|
||
|
|
- [JacksonConfig.java](file://crm-base/src/main/java/com/crm/base/config/JacksonConfig.java)
|
||
|
|
- [Knife4jConfig.java](file://crm-base/src/main/java/com/crm/base/config/Knife4jConfig.java)
|
||
|
|
- [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java)
|
||
|
|
- [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java)
|
||
|
|
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
|
||
|
|
- [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java)
|
||
|
|
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
|
||
|
|
- [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java)
|
||
|
|
- [CommonConstants.java](file://crm-base/src/main/java/com/crm/base/constant/CommonConstants.java)
|
||
|
|
- [BaseDTO.java](file://crm-base/src/main/java/com/crm/base/domain/dto/BaseDTO.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)
|
||
|
|
- [HasValueEnum.java](file://crm-base/src/main/java/com/crm/base/domain/enums/HasValueEnum.java)
|
||
|
|
- [StatusEnum.java](file://crm-base/src/main/java/com/crm/base/domain/enums/StatusEnum.java)
|
||
|
|
- [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java)
|
||
|
|
- [MissingParameterException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/MissingParameterException.java)
|
||
|
|
- [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java)
|
||
|
|
- [ResourceNotExistException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/ResourceNotExistException.java)
|
||
|
|
- [BaseParam.java](file://crm-base/src/main/java/com/crm/base/domain/param/BaseParam.java)
|
||
|
|
- [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java)
|
||
|
|
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
|
||
|
|
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
|
||
|
|
- [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java)
|
||
|
|
- [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java)
|
||
|
|
- [DataOwnership.java](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.java)
|
||
|
|
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
|
||
|
|
- [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.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)
|
||
|
|
- [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java)
|
||
|
|
- [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java)
|
||
|
|
- [AssertUtils.java](file://crm-base/src/main/java/com/crm/base/utils/AssertUtils.java)
|
||
|
|
- [BeanCopyUtils.java](file://crm-base/src/main/java/com/crm/base/utils/BeanCopyUtils.java)
|
||
|
|
- [EnumUtils.java](file://crm-base/src/main/java/com/crm/base/utils/EnumUtils.java)
|
||
|
|
- [ExcelUtil.java](file://crm-base/src/main/java/com/crm/base/utils/ExcelUtil.java)
|
||
|
|
- [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java)
|
||
|
|
- [ServletUtils.java](file://crm-base/src/main/java/com/crm/base/utils/ServletUtils.java)
|
||
|
|
- [TreeUtils.java](file://crm-base/src/main/java/com/crm/base/utils/TreeUtils.java)
|
||
|
|
</cite>
|
||
|
|
|
||
|
|
## 目录
|
||
|
|
1. [简介](#简介)
|
||
|
|
2. [项目结构](#项目结构)
|
||
|
|
3. [核心组件](#核心组件)
|
||
|
|
4. [架构总览](#架构总览)
|
||
|
|
5. [详细组件分析](#详细组件分析)
|
||
|
|
6. [依赖关系分析](#依赖关系分析)
|
||
|
|
7. [性能考虑](#性能考虑)
|
||
|
|
8. [故障排查指南](#故障排查指南)
|
||
|
|
9. [结论](#结论)
|
||
|
|
10. [附录](#附录)
|
||
|
|
|
||
|
|
## 简介
|
||
|
|
本文件为基于RBAC(角色-资源)的权限管理系统文档,覆盖角色管理、菜单权限控制与数据权限范围控制。重点说明实体设计(如 SysRole、SysMenu)、权限校验逻辑(PermissionServiceImpl)、数据权限类型(DataScopeEnum),以及权限注解使用、动态权限加载与权限缓存机制的实现细节和配置方法。读者可据此快速理解系统权限模型并正确扩展与使用。
|
||
|
|
|
||
|
|
## 项目结构
|
||
|
|
本项目采用多模块组织:
|
||
|
|
- crm-app:应用启动入口与全局配置
|
||
|
|
- crm-auth:认证与权限核心模块,包含RBAC实体、服务、安全拦截、第三方登录等
|
||
|
|
- crm-base:公共基础能力(异常、工具、通用配置、数据可见性上下文等)
|
||
|
|
- crm-file:文件服务(与本权限文档无直接关联)
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
graph TB
|
||
|
|
subgraph "应用层"
|
||
|
|
APP["crm-app<br/>启动与应用配置"]
|
||
|
|
end
|
||
|
|
subgraph "认证与权限"
|
||
|
|
AUTH["crm-auth<br/>RBAC实体/服务/安全/客户端"]
|
||
|
|
end
|
||
|
|
subgraph "基础能力"
|
||
|
|
BASE["crm-base<br/>异常/工具/通用配置/数据可见性"]
|
||
|
|
end
|
||
|
|
APP --> AUTH
|
||
|
|
AUTH --> BASE
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [CrmAppApplication.java:1-200](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java#L1-L200)
|
||
|
|
- [AuthApplication.java:1-200](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java#L1-L200)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [CrmAppApplication.java:1-200](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java#L1-L200)
|
||
|
|
- [AuthApplication.java:1-200](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java#L1-L200)
|
||
|
|
|
||
|
|
## 核心组件
|
||
|
|
- RBAC 实体
|
||
|
|
- SysRole:角色定义,承载角色标识、名称、状态等元信息
|
||
|
|
- SysMenu:菜单与按钮等资源定义,支持层级结构与类型区分
|
||
|
|
- SysUserRole、SysRoleMenu:用户-角色、角色-菜单的多对多关系表
|
||
|
|
- SysDept、SysUserDept:部门与用户部门关系,用于数据权限范围
|
||
|
|
- 权限服务
|
||
|
|
- PermissionServiceImpl:实现权限校验、菜单树构建、数据权限注入
|
||
|
|
- SysRoleServiceImpl、SysMenuServiceImpl:角色与菜单的CRUD与树形结构处理
|
||
|
|
- 安全与拦截
|
||
|
|
- SecurityConfig、JwtAuthenticationFilter:认证流程与JWT过滤
|
||
|
|
- DataScopeInterceptor、DataScopeTables:数据权限拦截与SQL改写
|
||
|
|
- AuthLoginUser、TokenService:当前登录用户上下文与令牌操作
|
||
|
|
- 数据权限
|
||
|
|
- DataScopeEnum:数据权限范围枚举(如全部、本部门、本部门及子部门、仅本人等)
|
||
|
|
- DataScope(注解)、DataScopeHelper、DataVisibilityContext:注解驱动的数据可见性控制
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [SysRole.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java#L1-L200)
|
||
|
|
- [SysMenu.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java#L1-L200)
|
||
|
|
- [SysUserRole.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java#L1-L200)
|
||
|
|
- [SysRoleMenu.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java#L1-L200)
|
||
|
|
- [SysDept.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java#L1-L200)
|
||
|
|
- [SysUserDept.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java#L1-L200)
|
||
|
|
- [PermissionServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java#L1-L200)
|
||
|
|
- [SysRoleServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java#L1-L200)
|
||
|
|
- [SysMenuServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java#L1-L200)
|
||
|
|
- [SecurityConfig.java:1-200](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java#L1-L200)
|
||
|
|
- [JwtAuthenticationFilter.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java#L1-L200)
|
||
|
|
- [DataScopeInterceptor.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java#L1-L200)
|
||
|
|
- [DataScopeTables.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java#L1-L200)
|
||
|
|
- [AuthLoginUser.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/AuthLoginUser.java#L1-L200)
|
||
|
|
- [TokenService.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java#L1-L200)
|
||
|
|
- [DataScopeEnum.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java#L1-L200)
|
||
|
|
- [DataScope.java:1-200](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java#L1-L200)
|
||
|
|
- [DataScopeHelper.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java#L1-L200)
|
||
|
|
- [DataVisibilityContext.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java#L1-L200)
|
||
|
|
|
||
|
|
## 架构总览
|
||
|
|
下图展示认证与权限在请求链路中的关键交互:从JWT鉴权到权限校验、再到数据权限注入与SQL改写。
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
sequenceDiagram
|
||
|
|
participant Client as "客户端"
|
||
|
|
participant API as "控制器"
|
||
|
|
participant SecCfg as "SecurityConfig"
|
||
|
|
participant JwtFilt as "JwtAuthenticationFilter"
|
||
|
|
participant Perm as "PermissionServiceImpl"
|
||
|
|
participant DSI as "DataScopeInterceptor"
|
||
|
|
participant DB as "数据库"
|
||
|
|
Client->>API : "HTTP 请求"
|
||
|
|
API->>SecCfg : "路由匹配与授权规则"
|
||
|
|
SecCfg->>JwtFilt : "解析JWT并建立认证上下文"
|
||
|
|
JwtFilt-->>API : "已认证用户"
|
||
|
|
API->>Perm : "调用权限校验(菜单/按钮)"
|
||
|
|
Perm-->>API : "返回是否允许访问"
|
||
|
|
API->>DSI : "进入数据权限拦截"
|
||
|
|
DSI->>DB : "根据数据权限范围改写SQL"
|
||
|
|
DB-->>API : "返回受限结果集"
|
||
|
|
API-->>Client : "响应"
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [SecurityConfig.java:1-200](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java#L1-L200)
|
||
|
|
- [JwtAuthenticationFilter.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java#L1-L200)
|
||
|
|
- [PermissionServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java#L1-L200)
|
||
|
|
- [DataScopeInterceptor.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java#L1-L200)
|
||
|
|
|
||
|
|
## 详细组件分析
|
||
|
|
|
||
|
|
### RBAC 实体设计与关系
|
||
|
|
- SysRole:角色主实体,提供角色ID、编码、名称、状态等字段
|
||
|
|
- SysMenu:菜单/按钮资源实体,支持类型(菜单、按钮、目录等)、排序、路径、图标等
|
||
|
|
- SysUserRole、SysRoleMenu:多对多关系表,支撑“用户-角色”、“角色-菜单”的授权映射
|
||
|
|
- SysDept、SysUserDept:部门维度,配合数据权限范围进行数据隔离
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
erDiagram
|
||
|
|
SYS_ROLE {
|
||
|
|
bigint id PK
|
||
|
|
varchar code UK
|
||
|
|
varchar name
|
||
|
|
int status
|
||
|
|
datetime created_at
|
||
|
|
datetime updated_at
|
||
|
|
}
|
||
|
|
SYS_MENU {
|
||
|
|
bigint id PK
|
||
|
|
varchar type
|
||
|
|
varchar path
|
||
|
|
varchar icon
|
||
|
|
int sort
|
||
|
|
int status
|
||
|
|
bigint parent_id
|
||
|
|
datetime created_at
|
||
|
|
datetime updated_at
|
||
|
|
}
|
||
|
|
SYS_USER_ROLE {
|
||
|
|
bigint id PK
|
||
|
|
bigint user_id FK
|
||
|
|
bigint role_id FK
|
||
|
|
}
|
||
|
|
SYS_ROLE_MENU {
|
||
|
|
bigint id PK
|
||
|
|
bigint role_id FK
|
||
|
|
bigint menu_id FK
|
||
|
|
}
|
||
|
|
SYS_DEPT {
|
||
|
|
bigint id PK
|
||
|
|
varchar name
|
||
|
|
bigint parent_id
|
||
|
|
int status
|
||
|
|
}
|
||
|
|
SYS_USER_DEPT {
|
||
|
|
bigint id PK
|
||
|
|
bigint user_id FK
|
||
|
|
bigint dept_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 : "分配给"
|
||
|
|
SYS_DEPT ||--o{ SYS_USER_DEPT : "包含"
|
||
|
|
SYS_USER ||--o{ SYS_USER_DEPT : "归属"
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [SysRole.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java#L1-L200)
|
||
|
|
- [SysMenu.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java#L1-L200)
|
||
|
|
- [SysUserRole.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java#L1-L200)
|
||
|
|
- [SysRoleMenu.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java#L1-L200)
|
||
|
|
- [SysDept.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java#L1-L200)
|
||
|
|
- [SysUserDept.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java#L1-L200)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [SysRole.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java#L1-L200)
|
||
|
|
- [SysMenu.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java#L1-L200)
|
||
|
|
- [SysUserRole.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java#L1-L200)
|
||
|
|
- [SysRoleMenu.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java#L1-L200)
|
||
|
|
- [SysDept.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java#L1-L200)
|
||
|
|
- [SysUserDept.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java#L1-L200)
|
||
|
|
|
||
|
|
### 权限校验与动态菜单加载(PermissionServiceImpl)
|
||
|
|
- 权限校验流程
|
||
|
|
- 获取当前用户及其角色集合
|
||
|
|
- 根据角色聚合菜单与按钮权限
|
||
|
|
- 针对接口或按钮进行白名单/黑名单校验
|
||
|
|
- 动态菜单加载
|
||
|
|
- 按用户角色查询菜单树,过滤无效节点
|
||
|
|
- 生成前端导航所需的树形结构
|
||
|
|
- 缓存策略
|
||
|
|
- 以用户或角色为键缓存菜单树与权限集合
|
||
|
|
- 在角色/菜单变更时主动失效相关缓存
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
Start(["进入权限校验"]) --> LoadUser["加载当前用户与角色"]
|
||
|
|
LoadUser --> CheckWhiteList{"是否在免检白名单?"}
|
||
|
|
CheckWhiteList --> |是| Allow["放行"]
|
||
|
|
CheckWhiteList --> |否| BuildPerms["构建权限集合(菜单/按钮)"]
|
||
|
|
BuildPerms --> HasPerm{"是否具备所需权限?"}
|
||
|
|
HasPerm --> |是| Allow
|
||
|
|
HasPerm --> |否| Deny["拒绝访问"]
|
||
|
|
Allow --> End(["结束"])
|
||
|
|
Deny --> End
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [PermissionServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java#L1-L200)
|
||
|
|
- [SysMenuServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java#L1-L200)
|
||
|
|
- [SysRoleServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java#L1-L200)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [PermissionServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java#L1-L200)
|
||
|
|
- [SysMenuServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java#L1-L200)
|
||
|
|
- [SysRoleServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java#L1-L200)
|
||
|
|
|
||
|
|
### 数据权限范围控制(DataScopeEnum 与拦截器)
|
||
|
|
- 数据权限类型
|
||
|
|
- 全部数据、本部门数据、本部门及子部门数据、仅本人数据等
|
||
|
|
- 注解驱动
|
||
|
|
- 在方法上使用 @DataScope 指定数据范围与目标表
|
||
|
|
- 拦截与SQL改写
|
||
|
|
- DataScopeInterceptor 读取上下文中的数据权限范围
|
||
|
|
- DataScopeTables 维护表与列的映射关系
|
||
|
|
- 通过 MyBatis Plus 的 SQL 注入器自动追加 WHERE 条件
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
sequenceDiagram
|
||
|
|
participant Controller as "业务控制器"
|
||
|
|
participant Interceptor as "DataScopeInterceptor"
|
||
|
|
participant Helper as "DataScopeHelper"
|
||
|
|
participant Tables as "DataScopeTables"
|
||
|
|
participant MP as "MyBatisPlus注入器"
|
||
|
|
participant DB as "数据库"
|
||
|
|
Controller->>Interceptor : "进入受保护方法"
|
||
|
|
Interceptor->>Helper : "解析@DataScope参数"
|
||
|
|
Helper->>Tables : "查找表/列映射"
|
||
|
|
Tables-->>Helper : "返回映射信息"
|
||
|
|
Helper-->>MP : "生成数据权限WHERE片段"
|
||
|
|
MP-->>DB : "执行带限制的SQL"
|
||
|
|
DB-->>Controller : "返回受限结果"
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [DataScope.java:1-200](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java#L1-L200)
|
||
|
|
- [DataScopeInterceptor.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java#L1-L200)
|
||
|
|
- [DataScopeTables.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java#L1-L200)
|
||
|
|
- [DataScopeHelper.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java#L1-L200)
|
||
|
|
- [CrmSqlInjector.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java#L1-L200)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [DataScopeEnum.java:1-200](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java#L1-L200)
|
||
|
|
- [DataScope.java:1-200](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java#L1-L200)
|
||
|
|
- [DataScopeInterceptor.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java#L1-L200)
|
||
|
|
- [DataScopeTables.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java#L1-L200)
|
||
|
|
- [DataScopeHelper.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java#L1-L200)
|
||
|
|
- [CrmSqlInjector.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java#L1-L200)
|
||
|
|
|
||
|
|
### 认证与安全配置(SecurityConfig、JwtAuthenticationFilter、TokenService)
|
||
|
|
- SecurityConfig:定义URL白名单、授权规则、跨域与异常处理器
|
||
|
|
- JwtAuthenticationFilter:解析JWT,填充认证上下文
|
||
|
|
- TokenService:生成、刷新、注销令牌,维护会话状态
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
classDiagram
|
||
|
|
class SecurityConfig {
|
||
|
|
+configure(http) void
|
||
|
|
+cors() CorsConfigurationSource
|
||
|
|
+exceptionHandler() SecurityExceptionHandlers
|
||
|
|
}
|
||
|
|
class JwtAuthenticationFilter {
|
||
|
|
+doFilter(request, response, chain) void
|
||
|
|
+parseToken(request) String
|
||
|
|
+setContext(token) void
|
||
|
|
}
|
||
|
|
class TokenService {
|
||
|
|
+createToken(user) String
|
||
|
|
+refreshToken(token) String
|
||
|
|
+logout(token) void
|
||
|
|
+validate(token) boolean
|
||
|
|
}
|
||
|
|
SecurityConfig --> JwtAuthenticationFilter : "注册过滤器"
|
||
|
|
JwtAuthenticationFilter --> TokenService : "验证/解析令牌"
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [SecurityConfig.java:1-200](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java#L1-L200)
|
||
|
|
- [JwtAuthenticationFilter.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java#L1-L200)
|
||
|
|
- [TokenService.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java#L1-L200)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [SecurityConfig.java:1-200](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java#L1-L200)
|
||
|
|
- [JwtAuthenticationFilter.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java#L1-L200)
|
||
|
|
- [TokenService.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java#L1-L200)
|
||
|
|
|
||
|
|
### 权限注解使用与最佳实践
|
||
|
|
- 接口级权限控制
|
||
|
|
- 在需要权限校验的方法上标注权限标识(如菜单code或按钮标识)
|
||
|
|
- 结合白名单跳过敏感接口校验
|
||
|
|
- 数据权限注解
|
||
|
|
- 在查询方法上标注 @DataScope,指定范围类型与目标表
|
||
|
|
- 确保 DataScopeTables 中已配置对应表的列映射
|
||
|
|
- 注意事项
|
||
|
|
- 避免在事务内频繁切换数据权限上下文
|
||
|
|
- 合理设置缓存失效时机,保证权限变更后即时生效
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [DataScope.java:1-200](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java#L1-L200)
|
||
|
|
- [DataScopeTables.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java#L1-L200)
|
||
|
|
- [PermissionServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java#L1-L200)
|
||
|
|
|
||
|
|
### 动态权限加载与缓存机制
|
||
|
|
- 动态加载
|
||
|
|
- 登录后根据用户角色拉取菜单树与按钮权限
|
||
|
|
- 将权限集合与菜单树写入缓存
|
||
|
|
- 缓存键设计
|
||
|
|
- 用户维度:user:{userId}:perms
|
||
|
|
- 角色维度:role:{roleId}:menuTree
|
||
|
|
- 缓存更新
|
||
|
|
- 角色/菜单变更触发失效
|
||
|
|
- 提供手动刷新接口供管理员使用
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [PermissionServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java#L1-L200)
|
||
|
|
- [SysMenuServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java#L1-L200)
|
||
|
|
- [SysRoleServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java#L1-L200)
|
||
|
|
|
||
|
|
### 配置方法与初始化
|
||
|
|
- 权限配置
|
||
|
|
- PermissionConfig:集中管理权限相关开关与默认值
|
||
|
|
- 安全配置
|
||
|
|
- SecurityConfig:URL白名单、跨域、异常处理器
|
||
|
|
- 数据初始化
|
||
|
|
- DataInitializer:初始化默认角色、菜单、管理员账号等
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [PermissionConfig.java:1-200](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java#L1-L200)
|
||
|
|
- [SecurityConfig.java:1-200](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java#L1-L200)
|
||
|
|
- [DataInitializer.java:1-200](file://crm-auth/src/main/java/com/crm/auth/config/DataInitializer.java#L1-L200)
|
||
|
|
|
||
|
|
## 依赖关系分析
|
||
|
|
- 模块依赖
|
||
|
|
- crm-auth 依赖 crm-base(异常、工具、数据可见性上下文)
|
||
|
|
- crm-app 依赖 crm-auth(作为应用入口)
|
||
|
|
- 组件耦合
|
||
|
|
- PermissionServiceImpl 依赖菜单与角色服务
|
||
|
|
- DataScopeInterceptor 依赖 DataScopeHelper 与 CrmSqlInjector
|
||
|
|
- SecurityConfig 依赖 JwtAuthenticationFilter 与异常处理器
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
graph LR
|
||
|
|
APP["crm-app"] --> AUTH["crm-auth"]
|
||
|
|
AUTH --> BASE["crm-base"]
|
||
|
|
AUTH --> |"依赖"| Mapper["Mapper层"]
|
||
|
|
AUTH --> |"依赖"| Service["Service层"]
|
||
|
|
Service --> |"依赖"| Mapper
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [CrmAppApplication.java:1-200](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java#L1-L200)
|
||
|
|
- [AuthApplication.java:1-200](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java#L1-L200)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [CrmAppApplication.java:1-200](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java#L1-L200)
|
||
|
|
- [AuthApplication.java:1-200](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java#L1-L200)
|
||
|
|
|
||
|
|
## 性能考虑
|
||
|
|
- 缓存优先
|
||
|
|
- 菜单树与权限集合应缓存至Redis,降低重复查询
|
||
|
|
- 合理设置过期时间与失效策略
|
||
|
|
- 批量与懒加载
|
||
|
|
- 菜单树构建尽量使用批量查询与懒加载
|
||
|
|
- 数据权限SQL优化
|
||
|
|
- 在 DataScopeTables 中精确映射表与列,避免全表扫描
|
||
|
|
- 为常用过滤列添加索引
|
||
|
|
|
||
|
|
[本节为通用指导,不直接分析具体文件]
|
||
|
|
|
||
|
|
## 故障排查指南
|
||
|
|
- 常见错误
|
||
|
|
- 未认证或令牌过期:检查 JwtAuthenticationFilter 与 TokenService 配置
|
||
|
|
- 权限不足:确认角色-菜单授权是否正确,缓存是否及时失效
|
||
|
|
- 数据权限不生效:检查 @DataScope 注解与 DataScopeTables 映射
|
||
|
|
- 定位步骤
|
||
|
|
- 查看全局异常处理器输出
|
||
|
|
- 开启调试日志,观察拦截器与SQL注入过程
|
||
|
|
- 核对缓存键与失效时机
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [GlobalExceptionHandlerAdvice.java:1-200](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java#L1-L200)
|
||
|
|
- [JwtAuthenticationFilter.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java#L1-L200)
|
||
|
|
- [TokenService.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java#L1-L200)
|
||
|
|
- [DataScopeInterceptor.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java#L1-L200)
|
||
|
|
- [DataScopeTables.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java#L1-L200)
|
||
|
|
|
||
|
|
## 结论
|
||
|
|
本权限管理系统以RBAC为核心,结合注解驱动的数据权限控制与拦截器实现的SQL改写,形成完整的权限校验与数据隔离方案。通过合理的缓存策略与配置化开关,可在保障安全性的同时提升性能与可维护性。建议在生产环境严格管理权限变更与缓存失效,确保权限一致性与实时性。
|
||
|
|
|
||
|
|
[本节为总结,不直接分析具体文件]
|
||
|
|
|
||
|
|
## 附录
|
||
|
|
- 术语
|
||
|
|
- RBAC:基于角色的访问控制
|
||
|
|
- 数据权限:基于用户所属组织或范围的查询限制
|
||
|
|
- 参考
|
||
|
|
- 实体与枚举:SysRole、SysMenu、DataScopeEnum
|
||
|
|
- 服务与拦截:PermissionServiceImpl、DataScopeInterceptor
|
||
|
|
- 配置与初始化:PermissionConfig、SecurityConfig、DataInitializer
|
||
|
|
|
||
|
|
[本节为补充信息,不直接分析具体文件]
|