# 安全框架 **本文引用的文件** - [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 的逻辑,增加新的过滤维度(如项目、客户等)。