|
|
|
|
# 安全配置与过滤器
|
|
|
|
|
|
|
|
|
|
<cite>
|
|
|
|
|
**本文引用的文件**
|
|
|
|
|
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
- [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)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
- [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)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
</cite>
|
|
|
|
|
|
|
|
|
|
## 更新摘要
|
|
|
|
|
**变更内容**
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- **新增API权限拦截器架构**:引入WebMvcConfig、ApiPermissionInterceptor、ApiPermissionCache和ApiPermissionRule,实现基于URL模式的动态权限验证
|
|
|
|
|
- **增强SecurityFilterChain**:集成新的API权限验证机制,形成"认证→授权→数据权限"的完整安全链
|
|
|
|
|
- **改进权限验证流程**:通过Caffeine缓存提升API权限匹配性能,支持Ant风格路径匹配
|
|
|
|
|
- **fail-open策略**:未注册规则的接口默认放行,已注册规则严格校验用户权限
|
|
|
|
|
|
|
|
|
|
## 目录
|
|
|
|
|
1. [简介](#简介)
|
|
|
|
|
2. [项目结构](#项目结构)
|
|
|
|
|
3. [核心组件](#核心组件)
|
|
|
|
|
4. [架构总览](#架构总览)
|
|
|
|
|
5. [详细组件分析](#详细组件分析)
|
|
|
|
|
6. [依赖关系分析](#依赖关系分析)
|
|
|
|
|
7. [性能考虑](#性能考虑)
|
|
|
|
|
8. [故障排查指南](#故障排查指南)
|
|
|
|
|
9. [结论](#结论)
|
|
|
|
|
10. [附录](#附录)
|
|
|
|
|
|
|
|
|
|
## 简介
|
|
|
|
|
本文件围绕 CRM 后端项目的安全配置与数据权限过滤进行系统化说明,重点覆盖:
|
|
|
|
|
- Spring Security 配置与安全策略(认证、授权、跨域、异常处理)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- 自定义过滤器链(JWT 认证过滤器、API权限拦截器、数据权限拦截器)
|
|
|
|
|
- API权限动态验证机制(基于URL模式匹配、Caffeine缓存、Ant路径匹配)
|
|
|
|
|
- 数据权限拦截器实现(注解驱动、表级映射、上下文传递)
|
|
|
|
|
- 初始化数据配置(角色、菜单、用户等基础数据)
|
|
|
|
|
- 安全异常处理与统一返回
|
|
|
|
|
- 跨域配置与最佳实践
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- **已更新:新增API权限拦截器架构,实现基于URL模式的动态权限验证**
|
|
|
|
|
|
|
|
|
|
目标是帮助开发者快速理解并正确使用系统的安全与数据权限能力。
|
|
|
|
|
|
|
|
|
|
## 项目结构
|
|
|
|
|
本项目采用多模块设计,安全相关能力主要分布在 crm-auth(认证与授权)和 crm-base(通用基础能力)两个模块中:
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- crm-auth:Spring Security 配置、JWT 认证、API权限拦截器、数据权限拦截器、权限配置、初始化数据、资源管理接口
|
|
|
|
|
- crm-base:跨域配置、全局异常处理、数据权限注解与工具、登录用户上下文
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
graph TB
|
|
|
|
|
subgraph "crm-auth"
|
|
|
|
|
A["SecurityConfig<br/>安全配置"]
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
B["WebMvcConfig<br/>MVC配置"]
|
|
|
|
|
C["ApiPermissionInterceptor<br/>API权限拦截器"]
|
|
|
|
|
D["ApiPermissionCache<br/>API权限缓存"]
|
|
|
|
|
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/>权限授予对象"]
|
|
|
|
|
end
|
|
|
|
|
subgraph "crm-base"
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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/>安全工具"]
|
|
|
|
|
end
|
|
|
|
|
A --> B
|
|
|
|
|
A --> F
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
A --> G
|
|
|
|
|
A --> J
|
|
|
|
|
A --> L
|
|
|
|
|
A --> M
|
|
|
|
|
B --> C
|
|
|
|
|
C --> D
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
D --> E
|
|
|
|
|
F --> P
|
|
|
|
|
P --> Q
|
|
|
|
|
Q --> R
|
|
|
|
|
G --> H
|
|
|
|
|
G --> V
|
|
|
|
|
G --> W
|
|
|
|
|
F --> I
|
|
|
|
|
M --> N
|
|
|
|
|
N --> O
|
|
|
|
|
S --> A
|
|
|
|
|
T --> A
|
|
|
|
|
```
|
|
|
|
|
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
**图表来源**
|
|
|
|
|
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
- [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)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
- [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)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
- [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)
|
|
|
|
|
|
|
|
|
|
## 核心组件
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- SecurityConfig:集中定义 Spring Security 策略,包括放行路径、鉴权规则、过滤器链装配、跨域与异常处理器集成。**所有接口现在都需要认证**。
|
|
|
|
|
- WebMvcConfig:**新增** - MVC配置类,注册API权限拦截器,在Spring Security之后、Controller之前执行。
|
|
|
|
|
- ApiPermissionInterceptor:**新增** - 动态权限拦截器,基于URL模式匹配和用户权限进行细粒度控制,支持Ant风格通配符。
|
|
|
|
|
- ApiPermissionCache:**新增** - API权限规则缓存,使用Caffeine缓存sys_menu中的button节点,提供高性能的权限匹配。
|
|
|
|
|
- ApiPermissionRule:**新增** - 权限规则记录类,封装URL模式和对应权限码的映射关系。
|
|
|
|
|
- JwtAuthenticationFilter:**已简化** - 从请求头提取 JWT 令牌,通过单一的 permissionResolver.resolve() 方法获取完整的授权信息,然后一次性构建 Authentication 对象并设置到 SecurityContext。
|
|
|
|
|
- DataScopeInterceptor:基于 @DataScope 注解与 DataScopeTables 映射,动态拼装 SQL 条件,实现行级数据权限控制。
|
|
|
|
|
- TokenService:提供令牌生成、校验、刷新等能力,支撑无状态认证。
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- PermissionResolver:**新增** - 权限解析引擎接口,定义 resolve() 和 visibleMenuTree() 方法,统一处理用户权限、角色和数据可见性的解析。
|
|
|
|
|
- PermissionResolverImpl:**新增** - 权限解析引擎实现,封装了「用户 → 角色 → 授权 → 资源」的完整查询链,支持 fail-closed 策略。
|
|
|
|
|
- PermissionGrant:**新增** - 权限授予对象,包含数据可见性、权限码并集和角色编码,提供 asAuthorities() 方法转换为 Spring Security authorities。
|
|
|
|
|
- PermissionConfig:权限相关的配置项(如角色-菜单映射、接口权限白名单)。
|
|
|
|
|
- DataInitializer:启动时初始化基础数据(角色、菜单、用户、部门等),保障系统可用。
|
|
|
|
|
- SecurityExceptionHandlers:统一捕获认证与授权异常,转换为标准错误响应。
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- ResourceController:**已重构为标准化的动作后缀模式,需要ADMIN角色权限才能访问**。
|
|
|
|
|
- CorsConfig:跨域配置,允许前端调用。
|
|
|
|
|
- GlobalExceptionHandlerAdvice:全局异常处理,统一错误码与消息。
|
|
|
|
|
- 数据权限注解与工具:@DataScope、@DataOwnership、DataScopeHelper、DataVisibilityContext、DataScopeLevel、LoginUser、SecurityUtils。
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
- [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)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
|
|
|
|
|
## 架构总览
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
下图展示了典型请求在安全与数据权限层面的处理流程:客户端请求进入后,先经过跨域与全局异常处理,再进入 Spring Security 过滤器链;未认证的请求由简化的 JWT 过滤器处理,通过统一的权限解析引擎获取完整的授权信息,认证成功后进入MVC层;此时API权限拦截器根据URL模式匹配用户权限,最后进入业务控制器;在执行数据访问前,数据权限拦截器根据注解与表映射动态注入 WHERE 条件,确保数据隔离。**特别地,/api/resources/** 路径现在需要完整的认证和 ADMIN 角色权限才能访问,这是安全强化的重要特性**。
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
sequenceDiagram
|
|
|
|
|
participant Client as "客户端"
|
|
|
|
|
participant Web as "Web层"
|
|
|
|
|
participant Security as "Spring Security"
|
|
|
|
|
participant Jwt as "JwtAuthenticationFilter"
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
participant Resolver as "PermissionResolver"
|
|
|
|
|
participant Mvc as "WebMvcConfig"
|
|
|
|
|
participant ApiPerm as "ApiPermissionInterceptor"
|
|
|
|
|
participant Controller as "ResourceController"
|
|
|
|
|
participant Interceptor as "DataScopeInterceptor"
|
|
|
|
|
participant DB as "数据库"
|
|
|
|
|
Client->>Web : HTTP 请求
|
|
|
|
|
Web->>Security : 进入过滤器链
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
alt 资源管理端点 (/api/resources/**)
|
|
|
|
|
Security->>Security : 检查ADMIN角色权限
|
|
|
|
|
Security-->>Jwt : 需要认证和角色验证
|
|
|
|
|
Jwt->>Jwt : 解析JWT令牌
|
|
|
|
|
Jwt->>Resolver : 调用resolve()获取完整授权
|
|
|
|
|
Resolver-->>Jwt : 返回PermissionGrant(可见性+权限+角色)
|
|
|
|
|
Jwt->>Jwt : 设置DataVisibilityContext
|
|
|
|
|
Jwt->>Jwt : 构建UsernamePasswordAuthenticationToken
|
|
|
|
|
Jwt-->>Security : 设置SecurityContext
|
|
|
|
|
Security-->>Mvc : 放行至MVC层
|
|
|
|
|
Mvc->>ApiPerm : API权限拦截器
|
|
|
|
|
ApiPerm->>ApiPerm : URL模式匹配
|
|
|
|
|
ApiPerm->>ApiPerm : 权限码验证
|
|
|
|
|
ApiPerm-->>Controller : 权限验证通过
|
|
|
|
|
else 其他受保护接口
|
|
|
|
|
Security->>Jwt : 解析JWT并构建认证
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
Jwt->>Resolver : 调用resolve()获取授权
|
|
|
|
|
Resolver-->>Jwt : 返回完整授权信息
|
|
|
|
|
Jwt-->>Security : 设置SecurityContext
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
Security-->>Mvc : 放行至MVC层
|
|
|
|
|
Mvc->>ApiPerm : API权限拦截器
|
|
|
|
|
ApiPerm-->>Controller : 权限验证通过
|
|
|
|
|
else 公开接口
|
|
|
|
|
Security-->>Mvc : 直接放行
|
|
|
|
|
Mvc-->>Controller : 直接放行
|
|
|
|
|
end
|
|
|
|
|
Controller->>Interceptor : 执行方法前触发拦截
|
|
|
|
|
Interceptor->>Interceptor : 读取@DataScope与表映射
|
|
|
|
|
Interceptor-->>Controller : 注入SQL条件
|
|
|
|
|
Controller->>DB : 执行查询/更新
|
|
|
|
|
DB-->>Controller : 返回结果
|
|
|
|
|
Controller-->>Client : 统一响应
|
|
|
|
|
```
|
|
|
|
|
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
**图表来源**
|
|
|
|
|
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
- [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)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
|
|
|
|
|
## 详细组件分析
|
|
|
|
|
|
|
|
|
|
### SecurityConfig 安全策略配置
|
|
|
|
|
- 功能要点
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- 定义放行路径(静态资源、健康检查、开放接口等)**仅包含登录接口、文档接口和其他必要公开接口**
|
|
|
|
|
- 配置认证与授权规则(按角色或权限标识控制)
|
|
|
|
|
- 装配自定义过滤器(JWT 认证过滤器)
|
|
|
|
|
- 集成跨域配置与异常处理器
|
|
|
|
|
- 禁用默认表单登录/CSRF(适用于前后端分离场景)
|
|
|
|
|
- 关键配置项
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- 白名单路径集合:**仅包含登录接口、文档接口和其他必要公开接口**
|
|
|
|
|
- 需要鉴权的 URL 模式与对应权限
|
|
|
|
|
- 过滤器链顺序(CORS -> 认证 -> 授权)
|
|
|
|
|
- 异常处理器注册
|
|
|
|
|
- 使用示例
|
|
|
|
|
- 新增需鉴权接口:在权限配置中添加 URL 与权限标识
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- 新增放行接口:添加到白名单列表(不推荐用于敏感接口)
|
|
|
|
|
- 调整跨域策略:通过 CorsConfig 统一配置
|
|
|
|
|
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
**重要更新** 资源管理端点 (/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)
|
|
|
|
|
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
### WebMvcConfig MVC配置(新增)
|
|
|
|
|
- **新增组件**:MVC配置类,负责注册API权限拦截器
|
|
|
|
|
- 功能要点
|
|
|
|
|
- 实现WebMvcConfigurer接口,重写addInterceptors方法
|
|
|
|
|
- 注册ApiPermissionInterceptor到所有/api/**路径
|
|
|
|
|
- 拦截器在Spring Security过滤器之后、Controller之前执行
|
|
|
|
|
- 确保API权限验证在业务逻辑执行前完成
|
|
|
|
|
- 执行时机
|
|
|
|
|
- Spring Security认证通过后
|
|
|
|
|
- Controller方法调用前
|
|
|
|
|
- 数据权限拦截器之前
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [WebMvcConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/WebMvcConfig.java)
|
|
|
|
|
|
|
|
|
|
### ApiPermissionInterceptor API权限拦截器(新增)
|
|
|
|
|
- **新增组件**:动态权限验证拦截器,基于URL模式匹配进行细粒度权限控制
|
|
|
|
|
- 功能要点
|
|
|
|
|
- 实现HandlerInterceptor接口,重写preHandle方法
|
|
|
|
|
- 使用AntPathMatcher进行URL模式匹配(支持*和**通配符)
|
|
|
|
|
- 从SecurityContext获取当前用户权限集合
|
|
|
|
|
- 支持fail-open策略:未匹配规则直接放行
|
|
|
|
|
- 匹配到规则但无权限时返回403状态码
|
|
|
|
|
- 处理流程
|
|
|
|
|
- 获取请求URI和所有匹配的权限规则
|
|
|
|
|
- 如果无匹配规则,直接放行(fail-open)
|
|
|
|
|
- 获取当前用户权限集合
|
|
|
|
|
- 检查用户是否拥有任一匹配规则的perms
|
|
|
|
|
- 有权限则放行,无权限返回403
|
|
|
|
|
- 性能优化
|
|
|
|
|
- 使用Caffeine缓存权限规则,避免频繁数据库查询
|
|
|
|
|
- AntPathMatcher预编译,提高匹配效率
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [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 API权限缓存(新增)
|
|
|
|
|
- **新增组件**:基于Caffeine的进程内缓存,存储API权限规则
|
|
|
|
|
- 功能要点
|
|
|
|
|
- 单key缓存整份规则列表,键名为"apiPermRules"
|
|
|
|
|
- 懒加载机制:首次访问时从数据库加载
|
|
|
|
|
- 支持主动失效:资源树变更后调用invalidate()重建缓存
|
|
|
|
|
- 只加载已启用且配置了apiUrl的button类型菜单
|
|
|
|
|
- 数据来源
|
|
|
|
|
- 从sys_menu表查询menuType=BUTTON且status=enabled的记录
|
|
|
|
|
- 过滤掉apiUrl为空或null的记录
|
|
|
|
|
- 转换为ApiPermissionRule对象列表
|
|
|
|
|
- 缓存策略
|
|
|
|
|
- 使用Caffeine默认配置,适合短期缓存场景
|
|
|
|
|
- 资源树变更时主动失效,保证数据一致性
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [ApiPermissionCache.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionCache.java)
|
|
|
|
|
|
|
|
|
|
### ApiPermissionRule 权限规则(新增)
|
|
|
|
|
- **新增组件**:权限规则记录类,使用Java record定义
|
|
|
|
|
- 数据结构
|
|
|
|
|
- pattern:Ant风格的URL模式(如/api/users/**)
|
|
|
|
|
- perms:对应的权限码(如crm:user:list)
|
|
|
|
|
- 特点
|
|
|
|
|
- 不可变对象,线程安全
|
|
|
|
|
- 简洁的数据载体,便于序列化和传输
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [ApiPermissionRule.java](file://crm-auth/src/main/java/com/crm/auth/security/ApiPermissionRule.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 认证过滤器(已简化)
|
|
|
|
|
- **重大简化**:移除了双重职责(数据范围初始化和权限创建),现在通过单一的 permissionResolver.resolve() 方法处理认证上下文加载和Spring Security权限创建
|
|
|
|
|
- 功能要点
|
|
|
|
|
- 从请求头提取 JWT 令牌
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- 调用 tokenService.verifyToken() 验证令牌有效性
|
|
|
|
|
- **通过 permissionResolver.resolve() 一次性获取完整的授权信息**(数据可见性 + 权限码 + 角色编码)
|
|
|
|
|
- 设置 DataVisibilityContext 用于数据权限控制
|
|
|
|
|
- 将 PermissionGrant 转换为 UsernamePasswordAuthenticationToken 并设置到 SecurityContext
|
|
|
|
|
- 异常处理
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- 令牌无效或缺失时跳过认证,交由后续过滤器处理
|
|
|
|
|
- 权限解析失败采用 fail-closed 策略,直接拒绝请求
|
|
|
|
|
- 使用示例
|
|
|
|
|
- 客户端在请求头携带 Authorization: Bearer <token>
|
|
|
|
|
- 服务端无需额外代码即可获取当前用户信息
|
|
|
|
|
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
**更新后的处理流程**:
|
|
|
|
|
1. 解析JWT令牌并验证
|
|
|
|
|
2. 调用 permissionResolver.resolve(userId) 获取完整的授权信息
|
|
|
|
|
3. 设置 DataVisibilityContext.load(grant.getVisibility())
|
|
|
|
|
4. 转换 PermissionGrant 为 Spring Security authorities
|
|
|
|
|
5. 构建 UsernamePasswordAuthenticationToken 并设置到 SecurityContext
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [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)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
|
|
|
|
|
### 权限解析引擎 PermissionResolver(新增)
|
|
|
|
|
- **新增组件**:统一的权限解析引擎,负责处理用户的所有授权事实
|
|
|
|
|
- 功能要点
|
|
|
|
|
- 解析用户的角色、权限码并集和数据可见性
|
|
|
|
|
- 支持 fail-closed 策略,解析失败直接抛出异常
|
|
|
|
|
- 提供 visibleMenuTree() 方法用于前端菜单渲染
|
|
|
|
|
- 核心方法
|
|
|
|
|
- `resolve(Long userId)`:解析用户的完整授权信息,返回 PermissionGrant
|
|
|
|
|
- `visibleMenuTree(Long userId)`:获取用户可见的菜单树(用于前端展示)
|
|
|
|
|
- 处理逻辑
|
|
|
|
|
- 查询用户角色并确定最宽的数据可见性档位
|
|
|
|
|
- 计算用户所属部门集合(主部门 + 兼职部门)
|
|
|
|
|
- 根据数据范围级别展开部门子树
|
|
|
|
|
- 收集所有授权的权限码(button类型且状态启用)
|
|
|
|
|
- 归一化角色编码(添加 ROLE_ 前缀)
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [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 authorities
|
|
|
|
|
- 自动处理角色编码的 ROLE_ 前缀归一化
|
|
|
|
|
- 数据结构
|
|
|
|
|
- `visibility`:DataVisibility 对象,包含用户ID、部门信息和数据范围
|
|
|
|
|
- `permCodes`:权限码集合(去重后的 button 权限)
|
|
|
|
|
- `roleCodes`:角色编码集合(原样存储,不带前缀)
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [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["解析注解参数<br/>表名/字段/范围级别"]
|
|
|
|
|
ResolveParams --> LoadContext["加载当前用户上下文"]
|
|
|
|
|
LoadContext --> BuildCondition["根据范围级别构建SQL条件"]
|
|
|
|
|
BuildCondition --> Inject["注入到查询语句"]
|
|
|
|
|
Inject --> End(["继续执行业务逻辑"])
|
|
|
|
|
Skip --> End
|
|
|
|
|
```
|
|
|
|
|
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
|
|
|
|
|
## 依赖关系分析
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- SecurityConfig 依赖 JwtAuthenticationFilter、PermissionConfig、CorsConfig、SecurityExceptionHandlers、**ResourceController(现需认证)**
|
|
|
|
|
- WebMvcConfig 依赖 ApiPermissionInterceptor,注册到/api/**路径
|
|
|
|
|
- ApiPermissionInterceptor 依赖 ApiPermissionCache 和 AntPathMatcher
|
|
|
|
|
- ApiPermissionCache 依赖 SysMenuMapper 和 Caffeine缓存
|
|
|
|
|
- DataScopeInterceptor 依赖 DataScopeTables、DataScopeHelper、DataVisibilityContext、DataScopeLevel
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- JwtAuthenticationFilter 依赖 TokenService、**PermissionResolver(新增)**、SecurityContext
|
|
|
|
|
- **PermissionResolverImpl 依赖多个 Mapper 和缓存服务,实现完整的权限解析逻辑**
|
|
|
|
|
- ResourceController 依赖 IResourceService、FileApi,**且需要 ADMIN 角色权限**
|
|
|
|
|
- 全局异常处理依赖 GlobalExceptionHandlerAdvice
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
classDiagram
|
|
|
|
|
class SecurityConfig {
|
|
|
|
|
+配置放行路径()
|
|
|
|
|
+配置鉴权规则()
|
|
|
|
|
+装配过滤器链()
|
|
|
|
|
}
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
class WebMvcConfig {
|
|
|
|
|
+注册API权限拦截器()
|
|
|
|
|
+配置/api/**路径()
|
|
|
|
|
}
|
|
|
|
|
class ApiPermissionInterceptor {
|
|
|
|
|
+URL模式匹配()
|
|
|
|
|
+权限码验证()
|
|
|
|
|
+fail-open策略()
|
|
|
|
|
}
|
|
|
|
|
class ApiPermissionCache {
|
|
|
|
|
+缓存权限规则()
|
|
|
|
|
+懒加载机制()
|
|
|
|
|
+主动失效()
|
|
|
|
|
}
|
|
|
|
|
class ApiPermissionRule {
|
|
|
|
|
+pattern : String
|
|
|
|
|
+perms : String
|
|
|
|
|
}
|
|
|
|
|
class JwtAuthenticationFilter {
|
|
|
|
|
+解析JWT()
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
+调用PermissionResolver()
|
|
|
|
|
+构建认证()
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
}
|
|
|
|
|
class PermissionResolver {
|
|
|
|
|
<<interface>>
|
|
|
|
|
+resolve(userId)
|
|
|
|
|
+visibleMenuTree(userId)
|
|
|
|
|
}
|
|
|
|
|
class PermissionResolverImpl {
|
|
|
|
|
+实现权限解析()
|
|
|
|
|
+处理数据可见性()
|
|
|
|
|
+计算权限码并集()
|
|
|
|
|
+归一化角色编码()
|
|
|
|
|
}
|
|
|
|
|
class PermissionGrant {
|
|
|
|
|
+封装授权信息()
|
|
|
|
|
+asAuthorities()
|
|
|
|
|
}
|
|
|
|
|
class DataScopeInterceptor {
|
|
|
|
|
+解析注解()
|
|
|
|
|
+构建SQL条件()
|
|
|
|
|
+注入查询()
|
|
|
|
|
}
|
|
|
|
|
class DataScopeTables {
|
|
|
|
|
+表字段映射()
|
|
|
|
|
}
|
|
|
|
|
class TokenService {
|
|
|
|
|
+生成令牌()
|
|
|
|
|
+校验令牌()
|
|
|
|
|
}
|
|
|
|
|
class PermissionConfig {
|
|
|
|
|
+权限映射()
|
|
|
|
|
}
|
|
|
|
|
class SecurityExceptionHandlers {
|
|
|
|
|
+处理安全异常()
|
|
|
|
|
}
|
|
|
|
|
class CorsConfig {
|
|
|
|
|
+配置跨域()
|
|
|
|
|
}
|
|
|
|
|
class GlobalExceptionHandlerAdvice {
|
|
|
|
|
+统一异常处理()
|
|
|
|
|
}
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
class ResourceController {
|
|
|
|
|
+listAll()
|
|
|
|
|
+saveOrUpdate()
|
|
|
|
|
+delete()
|
|
|
|
|
+uploadIcon()
|
|
|
|
|
+需要ADMIN角色权限()
|
|
|
|
|
}
|
|
|
|
|
class IResourceService {
|
|
|
|
|
+listAll()
|
|
|
|
|
+save()
|
|
|
|
|
+delete()
|
|
|
|
|
+uploadIcon()
|
|
|
|
|
}
|
|
|
|
|
class ResourceServiceImpl {
|
|
|
|
|
+实现资源服务逻辑()
|
|
|
|
|
+层级约束验证()
|
|
|
|
|
+字段必填校验()
|
|
|
|
|
+级联清理()
|
|
|
|
|
}
|
|
|
|
|
SecurityConfig --> JwtAuthenticationFilter : "装配"
|
|
|
|
|
SecurityConfig --> PermissionConfig : "读取"
|
|
|
|
|
SecurityConfig --> SecurityExceptionHandlers : "注册"
|
|
|
|
|
SecurityConfig --> CorsConfig : "集成"
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
SecurityConfig --> ResourceController : "受保护接口"
|
|
|
|
|
WebMvcConfig --> ApiPermissionInterceptor : "注册"
|
|
|
|
|
ApiPermissionInterceptor --> ApiPermissionCache : "依赖"
|
|
|
|
|
ApiPermissionCache --> ApiPermissionRule : "返回"
|
|
|
|
|
JwtAuthenticationFilter --> PermissionResolver : "依赖(新增)"
|
|
|
|
|
PermissionResolver <|.. PermissionResolverImpl : "实现"
|
|
|
|
|
PermissionResolverImpl --> PermissionGrant : "返回"
|
|
|
|
|
DataScopeInterceptor --> DataScopeTables : "读取映射"
|
|
|
|
|
DataScopeInterceptor --> TokenService : "间接依赖(用户上下文)"
|
|
|
|
|
JwtAuthenticationFilter --> TokenService : "使用"
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
ResourceController --> IResourceService : "依赖"
|
|
|
|
|
IResourceService --> ResourceServiceImpl : "实现"
|
|
|
|
|
```
|
|
|
|
|
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
**图表来源**
|
|
|
|
|
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
- [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)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
- [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)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
|
|
|
|
|
## 性能考虑
|
|
|
|
|
- JWT 校验开销:建议缓存用户权限与角色信息,减少频繁查询
|
|
|
|
|
- 数据权限 SQL 拼接:避免复杂子查询,优先使用索引字段(如 dept_id、user_id)
|
|
|
|
|
- 拦截器粒度:仅在必要方法上使用 @DataScope,降低不必要的解析成本
|
|
|
|
|
- 跨域预检:合理配置预检缓存,减少 OPTIONS 请求频率
|
|
|
|
|
- 异常处理:统一异常处理避免重复日志与堆栈打印
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- **权限验证优化**:通过严格的角色权限控制,提升系统安全性
|
|
|
|
|
- **API重构优化**:标准化的动作后缀模式提高了API的一致性和可维护性
|
|
|
|
|
- **权限解析优化**:新的 PermissionResolver 采用单次查询链,避免多次数据库访问
|
|
|
|
|
- **fail-closed策略**:权限解析失败直接拒绝请求,避免部分成功状态的性能浪费
|
|
|
|
|
- **API权限缓存优化**:使用Caffeine缓存权限规则,避免频繁数据库查询
|
|
|
|
|
- **AntPathMatcher优化**:预编译路径匹配器,提高URL匹配效率
|
|
|
|
|
- **懒加载机制**:权限规则按需加载,减少启动时间
|
|
|
|
|
|
|
|
|
|
[本节为通用指导,不直接分析具体文件]
|
|
|
|
|
|
|
|
|
|
## 故障排查指南
|
|
|
|
|
- 认证失败
|
|
|
|
|
- 检查请求头 Authorization 是否正确携带 Bearer 令牌
|
|
|
|
|
- 确认 TokenService 的密钥与算法配置一致
|
|
|
|
|
- 查看 SecurityExceptionHandlers 的错误码与消息
|
|
|
|
|
- 授权拒绝
|
|
|
|
|
- 核对 PermissionConfig 中的 URL 与权限标识
|
|
|
|
|
- 确认用户角色与菜单权限是否匹配
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- **检查资源管理接口是否需要 ADMIN 角色权限**
|
|
|
|
|
- **检查 PermissionResolver 的权限解析逻辑是否正常**
|
|
|
|
|
- 数据权限不生效
|
|
|
|
|
- 检查 @DataScope 注解参数是否与 DataScopeTables 映射一致
|
|
|
|
|
- 验证 DataVisibilityContext 中用户上下文是否正确设置
|
|
|
|
|
- 查看生成的 SQL 片段是否符合预期
|
|
|
|
|
- 跨域问题
|
|
|
|
|
- 检查 CorsConfig 的域名、方法与头部配置
|
|
|
|
|
- 确认预检请求是否被放行
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- **资源管理接口访问问题**
|
|
|
|
|
- 确认用户是否具有 ADMIN 角色权限
|
|
|
|
|
- 检查 JWT 令牌中是否包含正确的角色信息
|
|
|
|
|
- 验证 SecurityConfig 中的放行路径配置
|
|
|
|
|
- **API端点调用问题**
|
|
|
|
|
- 确认使用的是新的标准化动作后缀模式
|
|
|
|
|
- 检查POST请求的参数格式是否正确
|
|
|
|
|
- 验证DELETE操作是否使用了POST /api/resources/delete
|
|
|
|
|
- **权限解析问题**
|
|
|
|
|
- 检查 PermissionResolverImpl 的数据库查询是否正常
|
|
|
|
|
- 确认用户角色、菜单权限配置是否正确
|
|
|
|
|
- 验证 DataVisibilityContext 的加载和清理逻辑
|
|
|
|
|
- **API权限拦截问题**
|
|
|
|
|
- 检查ApiPermissionCache是否正确加载权限规则
|
|
|
|
|
- 确认SysMenu表中button类型的apiUrl配置是否正确
|
|
|
|
|
- 验证用户权限集合是否包含所需的perms
|
|
|
|
|
- 检查AntPathMatcher的路径匹配是否符合预期
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [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)
|
|
|
|
|
- [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)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
- [PermissionResolverImpl.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolverImpl.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)
|
|
|
|
|
|
|
|
|
|
## 结论
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
本项目的安全与数据权限体系以 Spring Security 为核心,结合 JWT 无状态认证与注解驱动的数据权限拦截器,实现了灵活且可扩展的安全控制。通过统一的异常处理与跨域配置,保障了前后端分离场景下的稳定交互。**最新的架构更新引入了统一的权限解析引擎(PermissionResolver)和API权限拦截器架构,JwtAuthenticationFilter经过重大简化,现在通过单一的 permissionResolver.resolve() 方法处理认证上下文加载和Spring Security权限创建,采用 fail-closed 策略确保安全性**。建议在新增接口时遵循以下最佳实践:
|
|
|
|
|
- 明确接口是否需要鉴权与数据权限
|
|
|
|
|
- 正确配置 @DataScope 与表映射
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- 完善权限配置与白名单(谨慎使用)
|
|
|
|
|
- 使用统一异常处理与返回格式
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- **对敏感接口实施严格的角色权限控制**
|
|
|
|
|
- **遵循标准化的动作后缀API模式**
|
|
|
|
|
- **利用 PermissionResolver 进行统一的权限解析**
|
|
|
|
|
- **为需要细粒度权限控制的接口配置API权限规则**
|
|
|
|
|
|
|
|
|
|
[本节为总结性内容,不直接分析具体文件]
|
|
|
|
|
|
|
|
|
|
## 附录
|
|
|
|
|
- 配置文件参考
|
|
|
|
|
- application.yml(应用配置)
|
|
|
|
|
- 常用注解与工具
|
|
|
|
|
- @DataScope、@DataOwnership
|
|
|
|
|
- DataScopeHelper、DataVisibilityContext、SecurityUtils
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- **已更新的资源管理接口**
|
|
|
|
|
- GET /api/resources/list:获取全量资源树
|
|
|
|
|
- POST /api/resources/saveOrUpdate:新增或编辑节点
|
|
|
|
|
- POST /api/resources/delete:删除节点(表单参数)
|
|
|
|
|
- POST /api/resources/icon/upload:图标上传
|
|
|
|
|
- 所有接口现在都需要 ADMIN 角色权限
|
|
|
|
|
- 主要用于权限结构的初始化和维护,但需要完整认证
|
|
|
|
|
- **新增的权限解析组件**
|
|
|
|
|
- PermissionResolver:权限解析接口
|
|
|
|
|
- PermissionResolverImpl:权限解析实现
|
|
|
|
|
- PermissionGrant:权限授予对象
|
|
|
|
|
- 支持 fail-closed 策略和完整的授权信息查询
|
|
|
|
|
- **新增的API权限拦截器组件**
|
|
|
|
|
- WebMvcConfig:MVC配置,注册API权限拦截器
|
|
|
|
|
- ApiPermissionInterceptor:动态权限验证拦截器
|
|
|
|
|
- ApiPermissionCache:API权限规则缓存
|
|
|
|
|
- ApiPermissionRule:权限规则记录类
|
|
|
|
|
- 支持Ant风格路径匹配和fail-open策略
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [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)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
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)
|
|
|
|
|
- [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)
|
|
|
|
|
- [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)
|