# 安全框架
**本文引用的文件**
- [DataOwnership.java](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.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)
- [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)
- [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)
- [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)
- [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)
- [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java)
- [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java)
- [AuthService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java)
- [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java)
- [SysRoleMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysRoleMapper.java)
- [SysMenuMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysMenuMapper.java)
- [SysDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java)
- [SysUserRoleMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserRoleMapper.java)
- [SysUserDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserDeptMapper.java)
- [DataScopeIntegrationTest.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/DataScopeIntegrationTest.java)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件为安全框架的全面技术文档,聚焦数据所有权注解 DataOwnership 的使用、数据范围级别 DataScopeLevel 的配置与数据可见性上下文 DataVisibilityContext 的管理;说明 LoginUser 用户信息模型与 SecurityUtils 工具类的常用方法;解释数据权限控制的实现原理(拦截器机制、SQL 过滤、用户权限验证);并提供安全配置最佳实践与自定义权限控制扩展指导。
## 项目结构
安全能力主要分布在两个模块:
- crm-base:提供通用安全基础能力,包括数据所有权注解、数据范围级别枚举、数据可见性上下文、登录用户模型、安全工具类以及 MyBatis-Plus SQL 注入器。
- crm-auth:提供认证授权与安全配置,包括 JWT 过滤器、令牌服务、数据范围拦截器、表映射配置、权限配置与认证服务实现。
```mermaid
graph TB
subgraph "crm-base"
A["DataOwnership
注解"]
B["DataScopeLevel
数据范围级别"]
C["DataVisibilityContext
数据可见性上下文"]
D["LoginUser
用户信息模型"]
E["SecurityUtils
安全工具类"]
F["DataScopeHelper
数据范围辅助"]
G["CrmSqlInjector
SQL注入器"]
H["MybatisPlusConfig
MP配置"]
end
subgraph "crm-auth"
I["JwtAuthenticationFilter
JWT过滤器"]
J["TokenService
令牌服务"]
K["DataScopeInterceptor
数据范围拦截器"]
L["DataScopeTables
数据范围表映射"]
M["PermissionConfig
权限配置"]
N["SecurityConfig
安全配置"]
O["AuthLoginUser
认证用户"]
P["AuthService / Impl
认证服务"]
Q["Sys*Mapper
系统表映射"]
end
A --> F
B --> F
C --> F
D --> E
E --> C
F --> G
G --> H
I --> J
I --> O
K --> L
K --> C
M --> N
P --> Q
```
图表来源
- [DataOwnership.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.java#L1-L200)
- [DataScopeLevel.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java#L1-L200)
- [DataVisibilityContext.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java#L1-L200)
- [LoginUser.java:1-200](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java#L1-L200)
- [SecurityUtils.java:1-200](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.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)
- [MybatisPlusConfig.java:1-200](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.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)
- [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)
- [AuthLoginUser.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/AuthLoginUser.java#L1-L200)
- [AuthService.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java#L1-L200)
- [AuthServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java#L1-L200)
- [SysRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysRoleMapper.java#L1-L200)
- [SysMenuMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysMenuMapper.java#L1-L200)
- [SysDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java#L1-L200)
- [SysUserRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserRoleMapper.java#L1-L200)
- [SysUserDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserDeptMapper.java#L1-L200)
章节来源
- [DataOwnership.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.java#L1-L200)
- [DataScopeLevel.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java#L1-L200)
- [DataVisibilityContext.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java#L1-L200)
- [LoginUser.java:1-200](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java#L1-L200)
- [SecurityUtils.java:1-200](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.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)
- [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)
- [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)
- [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)
- [CrmSqlInjector.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java#L1-L200)
- [MybatisPlusConfig.java:1-200](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java#L1-L200)
- [AuthService.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java#L1-L200)
- [AuthServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java#L1-L200)
- [SysRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysRoleMapper.java#L1-L200)
- [SysMenuMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysMenuMapper.java#L1-L200)
- [SysDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java#L1-L200)
- [SysUserRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserRoleMapper.java#L1-L200)
- [SysUserDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserDeptMapper.java#L1-L200)
## 核心组件
- 数据所有权注解 DataOwnership:用于声明实体或查询的数据所有权策略,结合数据范围级别进行细粒度控制。
- 数据范围级别 DataScopeLevel:定义数据可见性的层级(如本人、本部门、本部门及子部门、全公司、自定义等),配合注解驱动权限过滤。
- 数据可见性上下文 DataVisibilityContext:线程级上下文,保存当前请求的可见范围、租户、组织等信息,贯穿整个请求生命周期。
- 登录用户模型 LoginUser:封装当前登录用户的身份、角色、部门、权限集合等关键信息,供业务层与工具类使用。
- 安全工具类 SecurityUtils:提供获取当前用户、校验权限、解析上下文等便捷方法,简化业务代码中的安全调用。
- 数据范围辅助 DataScopeHelper:聚合数据范围计算逻辑,基于上下文与注解生成过滤条件。
- SQL 注入器 CrmSqlInjector:在 MyBatis-Plus 执行前自动拼接数据范围过滤 SQL,实现无侵入式数据权限控制。
- 数据范围拦截器 DataScopeInterceptor:在请求进入 Service/Mapper 层时,根据注解与上下文设置数据可见范围。
- JWT 过滤器 JwtAuthenticationFilter:从请求头解析 Token,完成认证并填充 Security 上下文。
- 令牌服务 TokenService:负责 Token 的签发、校验、刷新与过期处理。
- 权限配置 PermissionConfig 与安全配置 SecurityConfig:统一注册过滤器、拦截器、跨域、接口鉴权规则等。
章节来源
- [DataOwnership.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.java#L1-L200)
- [DataScopeLevel.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java#L1-L200)
- [DataVisibilityContext.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java#L1-L200)
- [LoginUser.java:1-200](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java#L1-L200)
- [SecurityUtils.java:1-200](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.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)
- [DataScopeInterceptor.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.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)
- [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)
## 架构总览
整体流程分为三层:
- 接入层:JwtAuthenticationFilter 解析 Token,建立认证上下文;SecurityConfig 统一装配安全相关 Bean。
- 控制层:DataScopeInterceptor 根据注解与上下文设置数据可见范围;PermissionConfig 管理接口级权限策略。
- 数据层:CrmSqlInjector 在 SQL 执行前注入数据范围过滤条件;DataScopeHelper 计算具体过滤表达式;Sys*Mapper 读取用户角色、部门等权限数据。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Filter as "JwtAuthenticationFilter"
participant Token as "TokenService"
participant Interceptor as "DataScopeInterceptor"
participant Context as "DataVisibilityContext"
participant MP as "MyBatis-Plus"
participant Injector as "CrmSqlInjector"
participant Mapper as "Sys*Mapper"
Client->>Filter : "HTTP 请求(携带Token)"
Filter->>Token : "校验Token/解析用户"
Token-->>Filter : "返回用户信息"
Filter-->>Client : "通过认证"
Client->>Interceptor : "进入业务方法"
Interceptor->>Context : "设置数据可见范围"
Interceptor-->>Client : "继续执行业务"
MP->>Injector : "执行SQL前拦截"
Injector->>Context : "读取可见范围"
Injector->>Mapper : "注入过滤条件后执行"
Mapper-->>MP : "返回结果集"
```
图表来源
- [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)
- [DataVisibilityContext.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java#L1-L200)
- [CrmSqlInjector.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java#L1-L200)
- [SysRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysRoleMapper.java#L1-L200)
- [SysDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java#L1-L200)
- [SysUserRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserRoleMapper.java#L1-L200)
- [SysUserDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserDeptMapper.java#L1-L200)
## 详细组件分析
### 数据所有权注解 DataOwnership 与数据范围级别 DataScopeLevel
- DataOwnership 用于标注实体或查询方法,声明数据归属策略(如“仅本人”、“本部门”、“本部门及子部门”、“全公司”、“自定义”)。
- DataScopeLevel 枚举定义了不同数据可见性层级,通常与 DataOwnership 配合使用,决定最终生成的 SQL 过滤条件。
- 典型用法:在 Service 方法上添加注解,指定数据范围级别;或在实体类上声明默认的数据所有权策略。
```mermaid
classDiagram
class DataOwnership {
+value() String
+scope() DataScopeLevel
+excludeFields() String[]
}
class DataScopeLevel {
<>
+ALL
+DEPT_AND_CHILD
+DEPT_ONLY
+SELF
+CUSTOM
}
DataOwnership --> DataScopeLevel : "引用"
```
图表来源
- [DataOwnership.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.java#L1-L200)
- [DataScopeLevel.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java#L1-L200)
章节来源
- [DataOwnership.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.java#L1-L200)
- [DataScopeLevel.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java#L1-L200)
### 数据可见性上下文 DataVisibilityContext 管理
- DataVisibilityContext 以 ThreadLocal 形式存储当前请求的数据可见范围、租户、组织、用户标识等。
- 生命周期:请求开始时由拦截器初始化,业务方法中可通过工具类读取或更新,请求结束时清理。
- 常见操作:设置可见范围、获取当前用户、合并多来源权限、清空上下文避免内存泄漏。
```mermaid
flowchart TD
Start(["请求开始"]) --> InitCtx["初始化上下文"]
InitCtx --> SetScope["设置数据可见范围"]
SetScope --> Business["执行业务逻辑"]
Business --> ReadCtx["读取上下文参数"]
ReadCtx --> UpdateCtx{"需要更新上下文?"}
UpdateCtx --> |是| MergePerms["合并权限/范围"]
UpdateCtx --> |否| Continue["继续执行"]
MergePerms --> Continue
Continue --> Cleanup["请求结束清理上下文"]
Cleanup --> End(["请求结束"])
```
图表来源
- [DataVisibilityContext.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java#L1-L200)
- [DataScopeInterceptor.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java#L1-L200)
章节来源
- [DataVisibilityContext.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java#L1-L200)
- [DataScopeInterceptor.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java#L1-L200)
### LoginUser 用户信息模型与 SecurityUtils 工具类
- LoginUser 包含用户 ID、用户名、角色列表、部门信息、权限集合等,作为认证后的主体对象。
- SecurityUtils 提供便捷方法:获取当前 LoginUser、判断是否管理员、检查菜单/按钮权限、解析上下文中的范围信息等。
- 典型场景:在 Controller/Service 中快速访问当前用户与权限,减少样板代码。
```mermaid
classDiagram
class LoginUser {
+userId : String
+username : String
+roles : String[]
+depts : String[]
+permissions : Set~String~
+isAdmin() : boolean
+hasPermission(permission) : boolean
}
class SecurityUtils {
+getCurrentUser() : LoginUser
+getUserId() : String
+checkPermission(permission) : void
+getDataScope() : DataScopeLevel
}
SecurityUtils --> LoginUser : "使用"
```
图表来源
- [LoginUser.java:1-200](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java#L1-L200)
- [SecurityUtils.java:1-200](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java#L1-L200)
章节来源
- [LoginUser.java:1-200](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java#L1-L200)
- [SecurityUtils.java:1-200](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java#L1-L200)
### 数据权限控制实现原理
- 拦截器机制:DataScopeInterceptor 在方法执行前解析注解与上下文,设置 DataVisibilityContext 中的数据范围。
- SQL 过滤:CrmSqlInjector 在 MyBatis-Plus 执行 SQL 前,根据 DataVisibilityContext 动态注入 WHERE 条件,实现行级数据隔离。
- 用户权限验证:JwtAuthenticationFilter 与 TokenService 完成认证;PermissionConfig 与 SecurityConfig 管理接口级鉴权;AuthService 与 Sys*Mapper 加载角色、部门、菜单等权限数据。
```mermaid
sequenceDiagram
participant Controller as "Controller"
participant Interceptor as "DataScopeInterceptor"
participant Context as "DataVisibilityContext"
participant MP as "MyBatis-Plus"
participant Injector as "CrmSqlInjector"
participant Mapper as "Sys*Mapper"
Controller->>Interceptor : "进入受保护方法"
Interceptor->>Context : "设置数据范围"
Controller->>MP : "调用Service/Mapper"
MP->>Injector : "拦截SQL"
Injector->>Context : "读取数据范围"
Injector->>Mapper : "注入过滤条件执行"
Mapper-->>MP : "返回受限结果集"
```
图表来源
- [DataScopeInterceptor.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java#L1-L200)
- [DataVisibilityContext.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java#L1-L200)
- [CrmSqlInjector.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java#L1-L200)
- [SysRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysRoleMapper.java#L1-L200)
- [SysDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java#L1-L200)
- [SysUserRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserRoleMapper.java#L1-L200)
- [SysUserDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserDeptMapper.java#L1-L200)
章节来源
- [DataScopeInterceptor.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java#L1-L200)
- [CrmSqlInjector.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.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)
- [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)
- [AuthService.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java#L1-L200)
- [AuthServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java#L1-L200)
- [SysRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysRoleMapper.java#L1-L200)
- [SysDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java#L1-L200)
- [SysUserRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserRoleMapper.java#L1-L200)
- [SysUserDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserDeptMapper.java#L1-L200)
### 数据范围表映射 DataScopeTables
- DataScopeTables 维护需要应用数据范围过滤的表名与字段映射,确保 SQL 注入器能精准定位目标表与列。
- 支持按表维度配置不同的过滤字段(如 owner_id、dept_id 等),提高灵活性。
章节来源
- [DataScopeTables.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java#L1-L200)
### 认证与授权流程
- JwtAuthenticationFilter 从请求头提取 Token,调用 TokenService 校验并构建 AuthLoginUser。
- SecurityConfig 注册过滤器与全局安全策略;PermissionConfig 定义接口级权限规则。
- AuthServiceImpl 与 Sys*Mapper 协作加载用户角色、部门、菜单等权限数据,供后续鉴权使用。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Filter as "JwtAuthenticationFilter"
participant Token as "TokenService"
participant Config as "SecurityConfig"
participant Perm as "PermissionConfig"
participant Service as "AuthService"
participant Mapper as "Sys*Mapper"
Client->>Filter : "HTTP 请求(含Token)"
Filter->>Token : "校验Token"
Token-->>Filter : "返回用户信息"
Filter-->>Client : "放行"
Client->>Perm : "访问受保护接口"
Perm->>Service : "校验角色/菜单权限"
Service->>Mapper : "查询用户权限数据"
Mapper-->>Service : "返回权限集合"
Service-->>Perm : "鉴权结果"
Perm-->>Client : "允许/拒绝"
```
图表来源
- [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)
- [PermissionConfig.java:1-200](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java#L1-L200)
- [AuthService.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java#L1-L200)
- [AuthServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java#L1-L200)
- [SysRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysRoleMapper.java#L1-L200)
- [SysMenuMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysMenuMapper.java#L1-L200)
- [SysDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java#L1-L200)
- [SysUserRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserRoleMapper.java#L1-L200)
- [SysUserDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserDeptMapper.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)
- [PermissionConfig.java:1-200](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java#L1-L200)
- [AuthService.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java#L1-L200)
- [AuthServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java#L1-L200)
- [SysRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysRoleMapper.java#L1-L200)
- [SysMenuMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysMenuMapper.java#L1-L200)
- [SysDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java#L1-L200)
- [SysUserRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserRoleMapper.java#L1-L200)
- [SysUserDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserDeptMapper.java#L1-L200)
### 数据范围注解 DataScope 与辅助 DataScopeHelper
- DataScope 注解用于在方法或类级别声明数据范围策略,可与 DataOwnership 组合使用。
- DataScopeHelper 提供统一的范围计算逻辑,支持合并多个来源的权限、生成 SQL 片段、处理边界条件。
章节来源
- [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)
### MyBatis-Plus 集成与 SQL 注入器
- MybatisPlusConfig 启用自定义 SQL 注入器 CrmSqlInjector。
- CrmSqlInjector 在 SELECT/UPDATE/DELETE 前拦截,根据 DataVisibilityContext 注入 WHERE 条件,实现无侵入式数据权限控制。
章节来源
- [MybatisPlusConfig.java:1-200](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java#L1-L200)
- [CrmSqlInjector.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java#L1-L200)
### 集成测试示例
- DataScopeIntegrationTest 展示了如何在测试环境中验证数据范围过滤的正确性,包括不同用户与部门下的数据可见性。
章节来源
- [DataScopeIntegrationTest.java:1-200](file://crm-auth/src/test/java/com/crm/auth/security/scope/DataScopeIntegrationTest.java#L1-L200)
## 依赖关系分析
- 低耦合高内聚:DataOwnership、DataScopeLevel、DataVisibilityContext 位于 crm-base,被 crm-auth 复用,职责清晰。
- 关键依赖链:
- JwtAuthenticationFilter → TokenService → AuthLoginUser
- DataScopeInterceptor → DataVisibilityContext → CrmSqlInjector → Sys*Mapper
- PermissionConfig → SecurityConfig → 全局安全策略
```mermaid
graph LR
Base["crm-base"] --> Auth["crm-auth"]
Base --> |"DataOwnership/DataScopeLevel/DataVisibilityContext"| Auth
Auth --> |"JwtAuthenticationFilter/TokenService/DataScopeInterceptor"| Base
Auth --> |"Sys*Mapper"| DB[("数据库")]
```
图表来源
- [DataOwnership.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.java#L1-L200)
- [DataScopeLevel.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java#L1-L200)
- [DataVisibilityContext.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.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)
- [SysRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysRoleMapper.java#L1-L200)
- [SysDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java#L1-L200)
- [SysUserRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserRoleMapper.java#L1-L200)
- [SysUserDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserDeptMapper.java#L1-L200)
章节来源
- [DataOwnership.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.java#L1-L200)
- [DataScopeLevel.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java#L1-L200)
- [DataVisibilityContext.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.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)
- [SysRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysRoleMapper.java#L1-L200)
- [SysDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java#L1-L200)
- [SysUserRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserRoleMapper.java#L1-L200)
- [SysUserDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserDeptMapper.java#L1-L200)
## 性能考量
- 上下文管理:避免在高频路径中频繁创建/销毁对象,合理使用 ThreadLocal 并在 finally 块中清理。
- SQL 注入:尽量将数据范围条件下推到数据库层,减少应用层过滤开销;合理索引 dept_id、owner_id 等字段。
- 权限缓存:对角色、部门、菜单等静态或低频变更数据引入缓存,降低数据库压力。
- 拦截器链:最小化拦截器逻辑,避免复杂计算阻塞请求链路。
## 故障排查指南
- Token 无效或过期:检查 TokenService 的签名算法、密钥配置与有效期设置;确认 JwtAuthenticationFilter 是否正确解析请求头。
- 数据范围不生效:确认 DataScopeInterceptor 是否注册;检查 DataScopeTables 是否包含目标表;验证 DataVisibilityContext 是否被正确设置与清理。
- 权限校验失败:核对 PermissionConfig 的路径白名单与鉴权规则;检查 AuthServiceImpl 与 Sys*Mapper 的权限数据加载逻辑。
- SQL 注入异常:查看 CrmSqlInjector 的注入逻辑与 DataScopeHelper 的条件生成;确认 MybatisPlusConfig 是否启用自定义注入器。
章节来源
- [TokenService.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java#L1-200)
- [JwtAuthenticationFilter.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java#L1-200)
- [DataScopeInterceptor.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java#L1-200)
- [DataScopeTables.java:1-200](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java#L1-200)
- [DataVisibilityContext.java:1-200](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java#L1-200)
- [PermissionConfig.java:1-200](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java#L1-200)
- [AuthServiceImpl.java:1-200](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java#L1-200)
- [SysRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysRoleMapper.java#L1-200)
- [SysDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java#L1-200)
- [SysUserRoleMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserRoleMapper.java#L1-200)
- [SysUserDeptMapper.java:1-200](file://crm-auth/src/main/java/com/crm/auth/mapper/SysUserDeptMapper.java#L1-200)
- [CrmSqlInjector.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java#L1-200)
- [MybatisPlusConfig.java:1-200](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java#L1-200)
## 结论
本安全框架通过注解驱动的 DataOwnership 与 DataScopeLevel 实现灵活的数据范围控制,结合 DataVisibilityContext 与 CrmSqlInjector 完成无侵入式 SQL 过滤;JwtAuthenticationFilter 与 TokenService 保障认证安全;PermissionConfig 与 SecurityConfig 统一管理接口鉴权。建议在生产环境结合缓存与索引优化性能,并通过集成测试覆盖典型场景。
## 附录
- 最佳实践
- 在 Service 层使用 DataOwnership/DataScope 注解声明数据范围,避免在业务逻辑中硬编码过滤条件。
- 将静态权限数据(角色、菜单、部门树)缓存至 Redis,缩短鉴权路径。
- 为 dept_id、owner_id、tenant_id 等字段建立合适索引,提升数据范围过滤性能。
- 在单元测试中使用 DataScopeIntegrationTest 模式验证数据可见性与权限控制。
- 自定义扩展
- 新增数据范围级别:扩展 DataScopeLevel 枚举,并在 DataScopeHelper 中补充对应 SQL 生成逻辑。
- 自定义权限策略:实现自己的 PermissionChecker 并在 PermissionConfig 中注册。
- 扩展 SQL 注入器:继承 CrmSqlInjector 的逻辑,增加新的过滤维度(如项目、客户等)。