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