总览
核查结论:AirSky 实现了多层次细粒度权限控制,在中小型 B2B 系统里属较高水准。
图清单
一、做了哪些权限控制
| 层次 | 机制 | 事实锚点 |
|---|---|---|
| 功能权限(按钮/接口级) | RBAC,模块:资源:动作 三段式标识 | 322 处 RequirePermission(...),遍布所有 pkg/*/router/router.go |
| 菜单权限 | 角色↔菜单 与 租户↔菜单 双重交集 | rbac/permission.go:194 EffectiveMenuIDs = 租户授权 ∩ 角色授权 |
| 数据权限(行级/部门级) | 5 档 data_scope | middleware/data_scope.go:18-51 |
| 多租户隔离 | tenant_id 行级 + GORM Scope 兜底 | customer_service.go:29 middleware.TenantScope(tc) |
| 功能开关 | 租户级覆盖 + 全局回退 | middleware/feature_guard.go:39 |
| 权限审计 | 专表记录授权变更(操作人/类型/目标/变更详情/IP) | entity/sys_permission_audit_log.go |
| 前端按钮级 | v-permission 指令,无权限直接移除元素 | directive/auth/permission.ts:8 |
模型设计正:超管(*:*:*)、平台超管、租户管理员、普通角色分层清晰;多租户下做「租户授权 ∩ 角色授权」交集校验,避免越权拿到租户未购买的菜单;前后端权限标识一致。
1. 权限多层模型
flowchart TD REQ[请求到达接口] T[多租户隔离<br/>TenantScope 行级] F[功能权限<br/>RequirePermission] M[菜单权限<br/>角色∩租户交集] D[数据权限<br/>data_scope 5 档] FG[功能开关<br/>FeatureGuard] OK[放行] REQ --> T T --> F F --> M M --> FG FG --> D D --> OK
说明:租户隔离、功能权限、功能开关在中间件层强制;数据权限本应在 service 查询层附加,但目前未接入(见下)。
二、两个高价值问题(核查发现)
P0-1 权限校验零缓存,每请求多次打 DB
HasEffectivePermission(rbac/permission.go:266-292)每次现查 DB,且为 5 表 JOIN(sys_menu×sys_tenant_menu×sys_role_menu×sys_user_role×sys_role)。挂在 322 个接口上 = 几乎每个请求都跑一次该 JOIN,外加 IsTenantAdmin 再查一次角色表。
关键:constant/cache_key.go:8 已定义 CacheKeyRoleMenus 缓存 key,但全仓库无任何地方使用——基础设施备好了,缓存逻辑没落地。
P0-2 数据权限写好了却没接入业务(横向越权风险)
DataScopeFilter(5 档完整实现,有专门测试),但全仓库 grep,在 pkg/ 业务 service 里调用次数为 0,只有测试在用。
即数据权限目前是「纸面功能」:例如 customer_service.go 列表查询只挂了 TenantScope 和 filter,没挂 DataScopeFilter,结果同租户内任何有 crm:customer:list 权限的人都能看到全租户客户 —— 这是潜在的横向越权读取。
三、一句话总结
权限体系框架完整、设计规范,但有两处需尽快处理:(P0-2) DataScopeFilter 已实现却未接入任何业务查询,存在同租户横向越权读取风险;(P0-1) 权限校验完全无缓存,缓存 key 已定义却未使用,322 接口每请求跑 5 表 JOIN。一个是安全短板、一个是性能短板,且都「差最后一步落地」,投入产出比最高。
完整优化清单见 优化建议。