# 安全配置与过滤器
**本文引用的文件**
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [WebMvcConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/WebMvcConfig.java)
- [ApiPermissionInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionInterceptor.java)
- [ApiPermissionCache.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionCache.java)
- [ApiPermissionRule.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionRule.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)
- [SecurityExceptionHandlers.java](file://crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.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)
- [DataInitializer.java](file://crm-auth/src/main/java/com/crm/auth/config/DataInitializer.java)
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.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)
- [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)
- [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)
- [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)
- [ResourceController.java](file://crm-auth/src/main/java/com/crm/auth/controller/ResourceController.java)
- [IResourceService.java](file://crm-auth/src/main/java/com/crm/auth/service/IResourceService.java)
- [ResourceServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/ResourceServiceImpl.java)
- [ResourceNode.java](file://crm-auth/src/main/java/com/crm/auth/domain/dto/ResourceNode.java)
- [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java)
- [MenuType.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuType.java)
- [AuthProperties.java](file://crm-auth/src/main/java/com/crm/auth/config/AuthProperties.java)
- [AuthConstants.java](file://crm-auth/src/main/java/com/crm/auth/constant/AuthConstants.java)
- [application.yml](file://crm-app/src/main/resources/application.yml)
- [application.yml](file://crm-auth/src/main/resources/application.yml)
- [PermissionResolver.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolver.java)
- [PermissionResolverImpl.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolverImpl.java)
- [PermissionGrant.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionGrant.java)
## 更新摘要
**变更内容**
- **新增API权限拦截机制**:通过WebMvcConfig注册ApiPermissionInterceptor实现动态API权限控制
- **增强安全配置架构**:在Spring Security之后、Controller之前增加API级别的权限验证
- **引入Caffeine缓存**:使用ApiPermissionCache缓存API权限规则,提升性能
- **支持Ant路径匹配**:ApiPermissionInterceptor支持Ant风格的URL模式匹配(*和**)
- **fail-open策略**:未匹配任何规则的请求默认放行,提高系统灵活性
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件围绕 CRM 后端项目的安全配置与数据权限过滤进行系统化说明,重点覆盖:
- Spring Security 配置与安全策略(认证、授权、跨域、异常处理)
- **新增** API权限拦截机制(动态权限控制、Caffeine缓存、Ant路径匹配)
- 自定义过滤器链(JWT 认证过滤器、数据权限拦截器)
- 数据权限拦截器实现(注解驱动、表级映射、上下文传递)
- 初始化数据配置(角色、菜单、用户等基础数据)
- 安全异常处理与统一返回
- 跨域配置与最佳实践
- **已更新:新增WebMvcConfig注册的API权限拦截器,实现了Spring Security之后的细粒度权限控制**
目标是帮助开发者快速理解并正确使用系统的安全与数据权限能力。
## 项目结构
本项目采用多模块设计,安全相关能力主要分布在 crm-auth(认证与授权)和 crm-base(通用基础能力)两个模块中:
- crm-auth:Spring Security 配置、JWT 认证、API权限拦截器、数据权限拦截器、权限配置、初始化数据、资源管理接口
- crm-base:跨域配置、全局异常处理、数据权限注解与工具、登录用户上下文
```mermaid
graph TB
subgraph "crm-auth"
A["SecurityConfig
安全配置"]
B["WebMvcConfig
MVC配置"]
C["ApiPermissionInterceptor
API权限拦截器"]
D["ApiPermissionCache
权限缓存"]
E["ApiPermissionRule
权限规则"]
F["JwtAuthenticationFilter
JWT认证过滤器"]
G["DataScopeInterceptor
数据权限拦截器"]
H["DataScopeTables
表权限映射"]
I["TokenService
令牌服务"]
J["PermissionConfig
权限配置"]
K["DataInitializer
初始化数据"]
L["SecurityExceptionHandlers
安全异常处理"]
M["ResourceController
资源管理控制器"]
N["IResourceService
资源管理服务"]
O["ResourceServiceImpl
资源服务实现"]
P["PermissionResolver
权限解析接口"]
Q["PermissionResolverImpl
权限解析实现"]
R["PermissionGrant
权限授予对象"]
end
subgraph "crm-base"
S["CorsConfig
跨域配置"]
T["GlobalExceptionHandlerAdvice
全局异常处理"]
U["DataScope
数据权限注解"]
V["DataScopeHelper
数据权限工具"]
W["DataVisibilityContext
可见性上下文"]
X["DataOwnership
数据所有权注解"]
Y["DataScopeLevel
数据范围级别"]
Z["LoginUser
登录用户模型"]
AA["SecurityUtils
安全工具"]
end
A --> B
B --> C
C --> D
D --> E
A --> F
A --> G
A --> J
A --> L
A --> M
G --> H
G --> V
G --> W
F --> I
F --> P
P --> Q
Q --> R
M --> N
N --> O
S --> A
T --> A
```
图表来源
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [WebMvcConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/WebMvcConfig.java)
- [ApiPermissionInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionInterceptor.java)
- [ApiPermissionCache.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionCache.java)
- [ApiPermissionRule.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionRule.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.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)
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
- [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java)
- [DataInitializer.java](file://crm-auth/src/main/java/com/crm/auth/config/DataInitializer.java)
- [SecurityExceptionHandlers.java](file://crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.java)
- [ResourceController.java](file://crm-auth/src/main/java/com/crm/auth/controller/ResourceController.java)
- [IResourceService.java](file://crm-auth/src/main/java/com/crm/auth/service/IResourceService.java)
- [ResourceServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/ResourceServiceImpl.java)
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.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)
- [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)
- [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)
- [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)
- [PermissionResolver.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolver.java)
- [PermissionResolverImpl.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolverImpl.java)
- [PermissionGrant.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionGrant.java)
章节来源
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [WebMvcConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/WebMvcConfig.java)
- [ApiPermissionInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionInterceptor.java)
- [ResourceController.java](file://crm-auth/src/main/java/com/crm/auth/controller/ResourceController.java)
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
## 核心组件
- SecurityConfig:集中定义 Spring Security 策略,包括放行路径、鉴权规则、过滤器链装配、跨域与异常处理器集成。**所有接口现在都需要认证**。
- **新增 WebMvcConfig**:注册API权限拦截器,在Spring Security之后、Controller之前执行权限验证。
- **新增 ApiPermissionInterceptor**:动态API权限拦截器,基于Ant路径匹配和用户权限码进行细粒度控制。
- **新增 ApiPermissionCache**:使用Caffeine缓存API权限规则,提升性能。
- **新增 ApiPermissionRule**:API权限规则记录,包含URL模式和权限码映射。
- JwtAuthenticationFilter:**已重构**从请求头解析 JWT 并构建认证信息,注入到 SecurityContext。现在使用新的PermissionResolver权限解析引擎。
- DataScopeInterceptor:基于 @DataScope 注解与 DataScopeTables 映射,动态拼装 SQL 条件,实现行级数据权限控制。
- TokenService:提供令牌生成、校验、刷新等能力,支撑无状态认证。
- PermissionConfig:权限相关的配置项(如角色-菜单映射、接口权限白名单)。
- DataInitializer:启动时初始化基础数据(角色、菜单、用户、部门等),保障系统可用。
- SecurityExceptionHandlers:统一捕获认证与授权异常,转换为标准错误响应。
- ResourceController:**已重构为标准化的动作后缀模式,需要ADMIN角色权限才能访问**。
- CorsConfig:跨域配置,允许前端调用。
- GlobalExceptionHandlerAdvice:全局异常处理,统一错误码与消息。
- **新增** PermissionResolver:统一的权限解析接口,负责用户权限、角色和数据可见性的计算。
- **新增** PermissionResolverImpl:权限解析引擎的具体实现,集中处理复杂的权限逻辑。
- **新增** PermissionGrant:权限授予对象,封装用户的完整授权信息。
- 数据权限注解与工具:@DataScope、@DataOwnership、DataScopeHelper、DataVisibilityContext、DataScopeLevel、LoginUser、SecurityUtils。
章节来源
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [WebMvcConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/WebMvcConfig.java)
- [ApiPermissionInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionInterceptor.java)
- [ApiPermissionCache.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionCache.java)
- [ApiPermissionRule.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionRule.java)
- [ResourceController.java](file://crm-auth/src/main/java/com/crm/auth/controller/ResourceController.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.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)
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
- [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java)
- [DataInitializer.java](file://crm-auth/src/main/java/com/crm/auth/config/DataInitializer.java)
- [SecurityExceptionHandlers.java](file://crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.java)
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.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)
- [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)
- [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)
- [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)
- [PermissionResolver.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolver.java)
- [PermissionResolverImpl.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolverImpl.java)
- [PermissionGrant.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionGrant.java)
## 架构总览
下图展示了典型请求在安全与数据权限层面的处理流程:客户端请求进入后,先经过跨域与全局异常处理,再进入 Spring Security 过滤器链;未认证的请求由 JWT 过滤器处理,认证成功后进入业务控制器;**新增的API权限拦截器在Spring Security之后、Controller之前执行,基于Ant路径匹配和用户权限码进行细粒度控制**;在执行数据访问前,数据权限拦截器根据注解与表映射动态注入 WHERE 条件,确保数据隔离。**特别地,/api/resources/** 路径现在需要完整的认证和 ADMIN 角色权限才能访问,这是安全强化的重要特性**。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Web as "Web层"
participant Security as "Spring Security"
participant Jwt as "JwtAuthenticationFilter"
participant Resolver as "PermissionResolver"
participant ApiPerm as "ApiPermissionInterceptor"
participant Controller as "ResourceController"
participant Interceptor as "DataScopeInterceptor"
participant DB as "数据库"
Client->>Web : HTTP 请求
Web->>Security : 进入过滤器链
alt 资源管理端点 (/api/resources/**)
Security->>Security : 检查ADMIN角色权限
Security-->>Jwt : 需要认证和角色验证
Jwt->>Jwt : 解析JWT并获取用户ID
Jwt->>Resolver : 调用resolve(userId)
Resolver-->>Jwt : 返回PermissionGrant
Jwt->>Jwt : grant.asAuthorities()生成授权
Jwt-->>Security : 设置SecurityContext
Security-->>ApiPerm : 放行至API权限拦截器
else 其他受保护接口
Security->>Jwt : 解析JWT并构建认证
Jwt-->>Security : 设置SecurityContext
Security-->>ApiPerm : 放行至API权限拦截器
else 公开接口
Security-->>ApiPerm : 直接放行
end
ApiPerm->>ApiPerm : Ant路径匹配与权限验证
alt 匹配规则且有权
ApiPerm-->>Controller : 验证通过,放行至控制器
else 无权限或无匹配
ApiPerm-->>Client : 返回403 Forbidden
end
Controller->>Interceptor : 执行方法前触发拦截
Interceptor->>Interceptor : 读取@DataScope与表映射
Interceptor-->>Controller : 注入SQL条件
Controller->>DB : 执行查询/更新
DB-->>Controller : 返回结果
Controller-->>Client : 统一响应
```
图表来源
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [WebMvcConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/WebMvcConfig.java)
- [ApiPermissionInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionInterceptor.java)
- [ApiPermissionCache.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionCache.java)
- [ResourceController.java](file://crm-auth/src/main/java/com/crm/auth/controller/ResourceController.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.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)
- [PermissionResolver.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolver.java)
- [PermissionResolverImpl.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolverImpl.java)
- [PermissionGrant.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionGrant.java)
## 详细组件分析
### WebMvcConfig MVC配置
- 功能要点
- **新增** 注册API权限拦截器到Spring MVC拦截器链
- 拦截所有 `/api/**` 路径的请求
- 在Spring Security过滤器之后、Controller之前执行
- 实现细粒度的API级别权限控制
- 关键配置
- 通过 `addInterceptors()` 方法注册拦截器
- 使用 `addPathPatterns("/api/**")` 指定拦截路径
- 依赖注入 `ApiPermissionInterceptor` 实例
- 执行时机
- Spring Security认证通过后执行
- Controller方法调用前执行
- 基于用户权限码进行最终授权判断
**重要更新** 这是全新的MVC配置类,为系统增加了API级别的权限控制能力,弥补了Spring Security粗粒度授权的不足。
章节来源
- [WebMvcConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/WebMvcConfig.java)
### ApiPermissionInterceptor API权限拦截器
- 功能要点
- **新增** 动态API权限拦截器,实现基于权限码的细粒度控制
- 支持Ant风格的路径匹配(*单层通配,**多层通配)
- 采用fail-open策略:未匹配任何规则则放行
- 匹配到规则但用户无对应perms则返回403 Forbidden
- 直接从SecurityContext获取用户权限信息进行验证
- 核心逻辑
- 从ApiPermissionCache获取所有权限规则
- 使用AntPathMatcher进行URL模式匹配
- 从SecurityContextHolder获取当前用户权限集合
- 检查用户是否拥有任一匹配规则的perms
- 无权限时记录日志并返回403响应
- 性能优化
- 使用Caffeine缓存权限规则,避免频繁数据库查询
- 资源树变更时主动失效缓存
- 使用示例
- 在sys_menu表中配置按钮类型的权限点
- 设置apiUrl字段为API路径模式(如 /api/users/**)
- 设置perms字段为权限码(如 crm:user:list)
**重要更新** 这是全新的API权限拦截器,提供了比Spring Security更灵活的权限控制机制,支持动态配置和Ant路径匹配。
章节来源
- [ApiPermissionInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionInterceptor.java)
- [ApiPermissionCache.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionCache.java)
### ApiPermissionCache 权限缓存
- 功能要点
- **新增** 使用Caffeine实现的进程内缓存
- 缓存sys_menu表中已注册的button节点权限规则
- 单key缓存整份规则列表,简化缓存管理
- 支持主动失效机制,资源树变更时重建缓存
- 核心方法
- `getRules()`:懒加载获取有效规则列表
- `invalidate()`:主动失效缓存,下次请求重建
- `loadRules()`:从数据库加载启用的button节点权限规则
- 数据源
- 查询sys_menu表中menuType=BUTTON的记录
- 过滤status='enabled'的启用权限点
- 过滤apiUrl不为空的有API映射的权限点
- 性能特性
- 首次访问时加载全部规则到内存
- 后续请求直接从缓存获取,零延迟
- 资源树变更后自动失效,保证数据一致性
**重要更新** 这是全新的权限缓存组件,为ApiPermissionInterceptor提供高性能的规则匹配支持。
章节来源
- [ApiPermissionCache.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionCache.java)
- [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java)
- [MenuType.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuType.java)
### ApiPermissionRule 权限规则
- 功能要点
- **新增** 不可变的权限规则记录
- 包含Ant风格的URL模式(pattern)和对应的权限码(perms)
- 使用Java record实现,简洁高效
- 核心属性
- `pattern`:Ant风格的URL模式,如 `/api/users/**`
- `perms`:对应的权限码,如 `crm:user:list`
- 使用场景
- 从SysMenu实体转换而来
- 用于ApiPermissionInterceptor的权限匹配
- 存储在ApiPermissionCache中进行缓存
**重要更新** 这是全新的权限规则数据结构,定义了API权限匹配的基本单元。
章节来源
- [ApiPermissionRule.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionRule.java)
### SecurityConfig 安全策略配置
- 功能要点
- 定义放行路径(静态资源、健康检查、开放接口等)**仅包含登录接口、文档接口和其他必要公开接口**
- 配置认证与授权规则(按角色或权限标识控制)
- 装配自定义过滤器(JWT 认证过滤器)
- 集成跨域配置与异常处理器
- 禁用默认表单登录/CSRF(适用于前后端分离场景)
- 关键配置项
- 白名单路径集合:**仅包含登录接口、文档接口和其他必要公开接口**
- 需要鉴权的 URL 模式与对应权限
- 过滤器链顺序(CORS -> 认证 -> 授权)
- 异常处理器注册
- 使用示例
- 新增需鉴权接口:在权限配置中添加 URL 与权限标识
- 新增放行接口:添加到白名单列表(不推荐用于敏感接口)
- 调整跨域策略:通过 CorsConfig 统一配置
**重要更新** 资源管理端点 (/api/resources/**) 已从白名单中移除,现在需要完整的认证和 ADMIN 角色权限才能访问,这符合 CRITICAL 安全规范要求。
章节来源
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java)
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.java)
### 资源管理接口 ResourceController
- 功能要点
- 提供统一的权限资源树管理接口
- 支持全量资源树查询、节点增删改、图标上传等功能
- **已重构为标准化的动作后缀模式,需要ADMIN角色权限才能访问**
- 完整的参数校验和业务逻辑验证
- 核心接口
- **GET /api/resources/list**:获取全量资源树(扁平数组)
- **POST /api/resources/saveOrUpdate**:新增或编辑节点
- **POST /api/resources/delete**:删除节点(含子节点检查,使用表单参数)
- POST /api/resources/icon/upload:图标文件上传
- 业务特性
- 层级约束验证(catalog/menu/button 类型限制)
- 字段必填校验(编辑模式下 type 不可变更)
- 级联清理(删除节点时清理角色授权引用)
- 文件上传校验(格式、大小限制)
**重要更新** 该控制器现在使用 @PreAuthorize("hasRole('ADMIN')") 注解,确保只有管理员用户才能访问资源管理功能,这是安全强化的关键措施。API端点已重构为标准化的动作后缀模式,所有写操作都使用POST请求配合相应的动作后缀。
章节来源
- [ResourceController.java](file://crm-auth/src/main/java/com/crm/auth/controller/ResourceController.java)
- [IResourceService.java](file://crm-auth/src/main/java/com/crm/auth/service/IResourceService.java)
- [ResourceServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/ResourceServiceImpl.java)
- [ResourceNode.java](file://crm-auth/src/main/java/com/crm/auth/domain/dto/ResourceNode.java)
### JwtAuthenticationFilter 认证过滤器
- 功能要点
- 从请求头提取 JWT 令牌
- 校验令牌有效性(签名、过期时间)
- **已重构** 使用新的 PermissionResolver.resolve() 方法解析用户权限
- 通过 PermissionGrant.asAuthorities() 生成 Spring Security 授权信息
- 直接加载 DataVisibilityContext 数据可见性上下文
- 将认证信息写入 SecurityContext
- 核心变更
- **移除了对 PermissionServiceImpl.initDataScopeContext() 的依赖**
- **新增 PermissionResolver 依赖注入**
- **简化了权限解析流程,一次调用获取完整授权信息**
- **使用 grant.asAuthorities() 直接生成 Spring Security authorities**
- 异常处理
- 令牌无效或缺失时抛出安全异常,交由统一异常处理器处理
- 使用示例
- 客户端在请求头携带 Authorization: Bearer
- 服务端无需额外代码即可获取当前用户信息
**重要更新** JwtAuthenticationFilter 已完全重构,现在使用统一的 PermissionResolver 权限解析引擎,简化了认证流程并提高了性能。
章节来源
- [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)
- [SecurityExceptionHandlers.java](file://crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.java)
- [PermissionResolver.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolver.java)
- [PermissionResolverImpl.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolverImpl.java)
- [PermissionGrant.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionGrant.java)
### 权限解析引擎 PermissionResolver
- 功能要点
- **新增** 统一的权限解析接口,集中处理用户权限、角色和数据可见性
- 一次 resolve() 调用获取用户的完整授权信息(数据可见性 + 权限码并集 + 角色编码)
- 支持 fail-closed 策略,解析失败即抛异常
- 提供 visibleMenuTree() 方法用于前端菜单渲染
- 核心方法
- `resolve(Long userId)`:解析用户的完整授权信息
- `visibleMenuTree(Long userId)`:获取用户可见的菜单树
- 实现特性
- 数据可见性计算:根据用户角色确定数据范围级别
- 权限码并集:合并所有角色的按钮权限,排除停用权限
- 角色编码归一化:自动添加 ROLE_ 前缀
- 部门树展开:支持子部门数据可见性
**重要更新** 这是全新的权限解析引擎,替代了旧的 PermissionServiceImpl.initDataScopeContext() 方法,提供了更清晰、更可维护的权限处理逻辑。
章节来源
- [PermissionResolver.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolver.java)
- [PermissionResolverImpl.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolverImpl.java)
### PermissionGrant 权限授予对象
- 功能要点
- **新增** 不可变的权限授予对象,封装用户的完整授权信息
- 包含数据可见性、权限码并集、角色编码三个核心属性
- 提供 asAuthorities() 方法直接生成 Spring Security 授权信息
- 角色编码自动归一化,确保 ROLE_ 前缀一致性
- 核心属性
- `getVisibility()`:数据可见性(部门集合 + 档位 + 子树展开)
- `getPermCodes()`:权限码并集(button 节点 perms 的去重集合)
- `getRoleCodes()`:角色编码集合(原样,不带 ROLE_ 前缀)
- Spring Security 集成
- `asAuthorities()` 方法自动生成 SimpleGrantedAuthority 列表
- 权限码原样注入,角色编码幂等归一到 ROLE_ 前缀
**重要更新** 这是全新的权限授予对象,为 JwtAuthenticationFilter 提供统一的授权信息封装。
章节来源
- [PermissionGrant.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionGrant.java)
### DataScopeInterceptor 数据权限拦截器
- 功能要点
- 基于 @DataScope 注解识别需要数据权限控制的接口
- 结合 DataScopeTables 的表名与字段映射,动态拼接 WHERE 条件
- 支持多种数据范围级别(全部、本部门、本人、自定义)
- 通过 DataVisibilityContext 传递当前用户的可见范围
- 处理流程
- 解析注解参数(表名、主键列、关联列、范围级别)
- 从登录用户上下文获取组织/角色信息
- 生成 SQL 片段并注入 MyBatis/MyBatis-Plus 查询
- 使用示例
- 在 Service 方法上添加 @DataScope(table="sys_user", scope=DataScopeLevel.DEPT)
- 查询自动附加 dept_id IN (当前用户所属部门) 的条件
章节来源
- [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)
- [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java)
#### 数据权限处理流程图
```mermaid
flowchart TD
Start(["进入拦截器"]) --> CheckAnnotation["检查是否包含@DataScope注解"]
CheckAnnotation --> |否| Skip["跳过数据权限处理"]
CheckAnnotation --> |是| ResolveParams["解析注解参数
表名/字段/范围级别"]
ResolveParams --> LoadContext["加载当前用户上下文"]
LoadContext --> BuildCondition["根据范围级别构建SQL条件"]
BuildCondition --> Inject["注入到查询语句"]
Inject --> End(["继续执行业务逻辑"])
Skip --> End
```
图表来源
- [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.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)
### DataScopeTables 表权限映射
- 功能要点
- 维护表名与数据权限字段的映射关系
- 支持主键列、关联列、外键列的配置
- 便于拦截器快速定位需要注入条件的列
- 使用示例
- 为新表添加映射条目,指定主键与关联字段
- 配合 @DataScope 注解生效
章节来源
- [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java)
### TokenService 令牌服务
- 功能要点
- 生成 JWT 令牌(含用户标识、角色、权限)
- 校验令牌签名与有效期
- 支持刷新与黑名单管理(可选)
- 使用示例
- 登录成功后调用生成令牌
- 后续请求携带令牌进行认证
章节来源
- [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)
### SecurityExceptionHandlers 安全异常处理
- 功能要点
- 捕获认证失败、授权拒绝等安全异常
- 统一转换为 Result 响应体(错误码、消息)
- 与全局异常处理器协作,保证一致性
- 使用示例
- 无需业务代码处理,直接返回标准错误响应
章节来源
- [SecurityExceptionHandlers.java](file://crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
### 初始化数据配置 DataInitializer
- 功能要点
- 启动时检查并插入基础数据(角色、菜单、用户、部门)
- 避免重复初始化,支持幂等
- 为权限与数据权限提供初始环境
- 使用示例
- 首次部署后自动创建管理员账号与基础菜单
章节来源
- [DataInitializer.java](file://crm-auth/src/main/java/com/crm/auth/config/DataInitializer.java)
### 跨域配置 CorsConfig
- 功能要点
- 允许指定域名、方法、头部与凭证
- 与 Spring Security 集成,确保预检请求放行
- 使用示例
- 配置前端域名与允许的请求头
章节来源
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.java)
### 数据权限注解与工具
- @DataScope:标注在方法上,声明数据权限策略
- @DataOwnership:标注实体类,声明数据所有权字段
- DataScopeHelper:提供 SQL 片段生成与上下文操作
- DataVisibilityContext:线程局部存储当前可见范围
- DataScopeLevel:枚举定义数据范围级别
- LoginUser:登录用户信息模型
- SecurityUtils:便捷获取当前用户与权限
章节来源
- [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.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)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
- [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.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)
### 认证配置 AuthProperties
- 功能要点
- 配置 JWT 密钥、有效期等认证参数
- 支持额外的放行 URL 配置
- 钉钉第三方认证配置
- 关键配置项
- JWT 签名密钥(生产环境必须修改)
- 登录态有效期(天)
- 额外放行的 URL 列表
- 钉钉应用配置(Client ID/Secret)
章节来源
- [AuthProperties.java](file://crm-auth/src/main/java/com/crm/auth/config/AuthProperties.java)
## 依赖关系分析
- SecurityConfig 依赖 JwtAuthenticationFilter、PermissionConfig、CorsConfig、SecurityExceptionHandlers、**ResourceController(现需认证)**
- **WebMvcConfig 依赖 ApiPermissionInterceptor**
- **ApiPermissionInterceptor 依赖 ApiPermissionCache、AntPathMatcher、SecurityContext**
- **ApiPermissionCache 依赖 SysMenuMapper、Caffeine缓存**
- DataScopeInterceptor 依赖 DataScopeTables、DataScopeHelper、DataVisibilityContext、DataScopeLevel
- **JwtAuthenticationFilter 依赖 TokenService、PermissionResolver、SecurityContext**
- **PermissionResolverImpl 依赖多个 Mapper 和 DeptTreeCache**
- ResourceController 依赖 IResourceService、FileApi,**且需要 ADMIN 角色权限**
- 全局异常处理依赖 GlobalExceptionHandlerAdvice
```mermaid
classDiagram
class SecurityConfig {
+配置放行路径()
+配置鉴权规则()
+装配过滤器链()
}
class WebMvcConfig {
+注册API权限拦截器()
+配置拦截路径()
}
class ApiPermissionInterceptor {
+Ant路径匹配()
+权限码验证()
+fail-open策略()
+403响应处理()
}
class ApiPermissionCache {
+Caffeine缓存()
+懒加载规则()
+主动失效()
+数据库查询()
}
class ApiPermissionRule {
+pattern()
+perms()
}
class JwtAuthenticationFilter {
+解析JWT()
+构建认证()
+使用PermissionResolver()
}
class PermissionResolver {
<>
+resolve(userId)
+visibleMenuTree(userId)
}
class PermissionResolverImpl {
+实现权限解析()
+计算数据可见性()
+生成权限码并集()
+处理角色编码()
}
class PermissionGrant {
+getVisibility()
+getPermCodes()
+getRoleCodes()
+asAuthorities()
}
class DataScopeInterceptor {
+解析注解()
+构建SQL条件()
+注入查询()
}
class DataScopeTables {
+表字段映射()
}
class TokenService {
+生成令牌()
+校验令牌()
}
class PermissionConfig {
+权限映射()
}
class SecurityExceptionHandlers {
+处理安全异常()
}
class CorsConfig {
+配置跨域()
}
class GlobalExceptionHandlerAdvice {
+统一异常处理()
}
class ResourceController {
+listAll()
+saveOrUpdate()
+delete()
+uploadIcon()
+需要ADMIN角色权限()
}
class IResourceService {
+listAll()
+save()
+delete()
+uploadIcon()
}
class ResourceServiceImpl {
+实现资源服务逻辑()
+层级约束验证()
+字段必填校验()
+级联清理()
}
SecurityConfig --> JwtAuthenticationFilter : "装配"
SecurityConfig --> PermissionConfig : "读取"
SecurityConfig --> SecurityExceptionHandlers : "注册"
SecurityConfig --> CorsConfig : "集成"
SecurityConfig --> ResourceController : "受保护接口"
WebMvcConfig --> ApiPermissionInterceptor : "注册"
ApiPermissionInterceptor --> ApiPermissionCache : "依赖"
ApiPermissionCache --> ApiPermissionRule : "缓存"
JwtAuthenticationFilter --> TokenService : "使用"
JwtAuthenticationFilter --> PermissionResolver : "依赖"
PermissionResolver <|.. PermissionResolverImpl : "实现"
PermissionResolverImpl --> PermissionGrant : "返回"
DataScopeInterceptor --> DataScopeTables : "读取映射"
DataScopeInterceptor --> TokenService : "间接依赖(用户上下文)"
ResourceController --> IResourceService : "依赖"
IResourceService --> ResourceServiceImpl : "实现"
```
图表来源
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [WebMvcConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/WebMvcConfig.java)
- [ApiPermissionInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionInterceptor.java)
- [ApiPermissionCache.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionCache.java)
- [ApiPermissionRule.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionRule.java)
- [ResourceController.java](file://crm-auth/src/main/java/com/crm/auth/controller/ResourceController.java)
- [IResourceService.java](file://crm-auth/src/main/java/com/crm/auth/service/IResourceService.java)
- [ResourceServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/ResourceServiceImpl.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.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)
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
- [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java)
- [SecurityExceptionHandlers.java](file://crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.java)
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [PermissionResolver.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolver.java)
- [PermissionResolverImpl.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolverImpl.java)
- [PermissionGrant.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionGrant.java)
章节来源
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [WebMvcConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/WebMvcConfig.java)
- [ApiPermissionInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionInterceptor.java)
- [ApiPermissionCache.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionCache.java)
- [ApiPermissionRule.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionRule.java)
- [ResourceController.java](file://crm-auth/src/main/java/com/crm/auth/controller/ResourceController.java)
- [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
- [PermissionResolver.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolver.java)
- [PermissionResolverImpl.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolverImpl.java)
- [PermissionGrant.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionGrant.java)
## 性能考虑
- JWT 校验开销:建议缓存用户权限与角色信息,减少频繁查询
- **新增API权限缓存**:使用Caffeine缓存API权限规则,避免频繁数据库查询
- **权限解析优化**:新的 PermissionResolver 引擎一次调用获取完整授权信息,避免了多次数据库查询
- **数据权限 SQL 拼接**:避免复杂子查询,优先使用索引字段(如 dept_id、user_id)
- **拦截器粒度**:仅在必要方法上使用 @DataScope,降低不必要的解析成本
- **跨域预检**:合理配置预检缓存,减少 OPTIONS 请求频率
- **异常处理**:统一异常处理避免重复日志与堆栈打印
- **权限验证优化**:通过严格的角色权限控制,提升系统安全性
- **API重构优化**:标准化的动作后缀模式提高了API的一致性和可维护性
- **缓存失效策略**:资源树变更时主动失效缓存,保证数据一致性
[本节为通用指导,不直接分析具体文件]
## 故障排查指南
- 认证失败
- 检查请求头 Authorization 是否正确携带 Bearer 令牌
- 确认 TokenService 的密钥与算法配置一致
- 查看 SecurityExceptionHandlers 的错误码与消息
- 授权拒绝
- 核对 PermissionConfig 中的 URL 与权限标识
- 确认用户角色与菜单权限是否匹配
- **检查资源管理接口是否需要 ADMIN 角色权限**
- **新增API权限问题**
- 检查sys_menu表中是否正确配置button类型的权限点
- 确认apiUrl字段是否与请求路径匹配
- 验证perms字段是否与用户权限码一致
- 检查ApiPermissionCache缓存是否正常加载
- **权限解析问题**
- 确认 PermissionResolver 实现正确注入
- 检查用户是否有正确的角色分配
- 验证权限码和角色编码格式
- 数据权限不生效
- 检查 @DataScope 注解参数是否与 DataScopeTables 映射一致
- 验证 DataVisibilityContext 中用户上下文是否正确设置
- 查看生成的 SQL 片段是否符合预期
- 跨域问题
- 检查 CorsConfig 的域名、方法与头部配置
- 确认预检请求是否被放行
- **资源管理接口访问问题**
- 确认用户是否具有 ADMIN 角色权限
- 检查 JWT 令牌中是否包含正确的角色信息
- 验证 SecurityConfig 中的放行路径配置
- **API端点调用问题**
- 确认使用的是新的标准化动作后缀模式
- 检查POST请求的参数格式是否正确
- 验证DELETE操作是否使用了POST /api/resources/delete
- **缓存相关问题**
- 检查Caffeine缓存配置是否正常
- 确认资源树变更后缓存是否正确失效
- 查看ApiPermissionCache的日志输出
章节来源
- [SecurityExceptionHandlers.java](file://crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [ApiPermissionInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionInterceptor.java)
- [ApiPermissionCache.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionCache.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)
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [ResourceController.java](file://crm-auth/src/main/java/com/crm/auth/controller/ResourceController.java)
- [PermissionResolver.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolver.java)
- [PermissionResolverImpl.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolverImpl.java)
## 结论
本项目的安全与数据权限体系以 Spring Security 为核心,结合 JWT 无状态认证与注解驱动的数据权限拦截器,实现了灵活且可扩展的安全控制。通过统一的异常处理与跨域配置,保障了前后端分离场景下的稳定交互。**最新的架构重构引入了统一的 PermissionResolver 权限解析引擎,替换了旧的 PermissionServiceImpl.initDataScopeContext() 方法,简化了认证流程并提高了性能。同时,ResourceController 现在需要 ADMIN 角色权限才能访问,并且API端点已重构为标准化的动作后缀模式,这符合 CRITICAL 安全规范要求。新增的WebMvcConfig和ApiPermissionInterceptor提供了更细粒度的API级别权限控制,通过Caffeine缓存提升了性能**。建议在新增接口时遵循以下最佳实践:
- 明确接口是否需要鉴权与数据权限
- 正确配置 @DataScope 与表映射
- 完善权限配置与白名单(谨慎使用)
- 使用统一异常处理与返回格式
- **对敏感接口实施严格的角色权限控制**
- **遵循标准化的动作后缀API模式**
- **利用新的 PermissionResolver 引擎进行权限解析**
- **在sys_menu中正确配置API权限点和权限码**
- **合理使用Caffeine缓存提升性能**
[本节为总结性内容,不直接分析具体文件]
## 附录
- 配置文件参考
- application.yml(应用配置)
- 常用注解与工具
- @DataScope、@DataOwnership
- DataScopeHelper、DataVisibilityContext、SecurityUtils
- **已更新的资源管理接口**
- GET /api/resources/list:获取全量资源树
- POST /api/resources/saveOrUpdate:新增或编辑节点
- POST /api/resources/delete:删除节点(表单参数)
- POST /api/resources/icon/upload:图标上传
- 所有接口现在都需要 ADMIN 角色权限
- 主要用于权限结构的初始化和维护,但需要完整认证
- **新增的权限解析组件**
- PermissionResolver:统一的权限解析接口
- PermissionResolverImpl:权限解析引擎实现
- PermissionGrant:权限授予对象,封装完整授权信息
- **新增的API权限控制组件**
- WebMvcConfig:MVC配置,注册API权限拦截器
- ApiPermissionInterceptor:动态API权限拦截器
- ApiPermissionCache:Caffeine缓存,缓存API权限规则
- ApiPermissionRule:API权限规则记录
- **新增的菜单实体扩展**
- SysMenu:新增apiUrl、perms、status等字段
- MenuType:定义catalog/menu/button三种类型
章节来源
- [application.yml](file://crm-app/src/main/resources/application.yml)
- [application.yml](file://crm-auth/src/main/resources/application.yml)
- [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.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)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
- [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java)
- [ResourceController.java](file://crm-auth/src/main/java/com/crm/auth/controller/ResourceController.java)
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [PermissionResolver.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolver.java)
- [PermissionResolverImpl.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolverImpl.java)
- [PermissionGrant.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionGrant.java)
- [WebMvcConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/WebMvcConfig.java)
- [ApiPermissionInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionInterceptor.java)
- [ApiPermissionCache.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionCache.java)
- [ApiPermissionRule.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionRule.java)
- [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java)
- [MenuType.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuType.java)