总览

airsky 总索引 | 权限体系分析 索引

核查结论:AirSky 实现了多层次细粒度权限控制,在中小型 B2B 系统里属较高水准。

图清单

一、做了哪些权限控制

层次机制事实锚点
功能权限(按钮/接口级)RBAC,模块:资源:动作 三段式标识322 处 RequirePermission(...),遍布所有 pkg/*/router/router.go
菜单权限角色↔菜单 与 租户↔菜单 双重交集rbac/permission.go:194 EffectiveMenuIDs = 租户授权 ∩ 角色授权
数据权限(行级/部门级)5 档 data_scopemiddleware/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

HasEffectivePermissionrbac/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 列表查询只挂了 TenantScopefilter没挂 DataScopeFilter,结果同租户内任何有 crm:customer:list 权限的人都能看到全租户客户 —— 这是潜在的横向越权读取

三、一句话总结

权限体系框架完整、设计规范,但有两处需尽快处理:(P0-2) DataScopeFilter 已实现却未接入任何业务查询,存在同租户横向越权读取风险(P0-1) 权限校验完全无缓存,缓存 key 已定义却未使用,322 接口每请求跑 5 表 JOIN。一个是安全短板、一个是性能短板,且都「差最后一步落地」,投入产出比最高。

完整优化清单见 优化建议