Skip to content

RBAC 同步规范

表结构见数据模型,菜单判断见算法说明的算法 B。

迁移概览

Legacy 继续写 usersmenu.qxqx_list;Beta 不做双写,而是通过 lims:rbac-sync 将这些数据镜像到 rbac_* 表。Beta 的权限判断读取快照,Legacy 仍是权限变更的唯一写入入口。

text
Legacy users / menu.qx / qx_list
        │ lims:rbac-sync

rbac_permissions / rbac_roles / rbac_user_permission_snapshots / rbac_menu_permissions


Beta 路由权限与菜单可见性

改用户组、权限字段或菜单规则后,先完成 Legacy 更新,再执行:

bash
php artisan lims:rbac-sync
php artisan lims:rbac-verify

如果同步结果与 Legacy 不一致,应先修正数据或同步逻辑;不要为临时恢复访问而放开生产环境的 RBAC。路由权限开关由 config/rbac.php 中的 RBAC_ENFORCE 控制。


命令

bash
cd beta
php artisan lims:rbac-sync [--fzx-id=] [--dry-run] [--report=path]
php artisan lims:rbac-verify [--sample-users=50] [--sample-menus=100]

代码位置

beta/app/Services/Rbac/Sync/
  PermissionCatalogSync.php              # P1–P2
  RoleSync.php                           # P3
  UserRoleSync.php                       # P4
  UserPermissionSnapshotSync.php         # P5
  MenuPermissionSync.php                 # P6
  RbacSyncReport.php
beta/app/Services/Rbac/Legacy/
  LegacyQxCatalogReader.php
  LegacyMenuReader.php
  LegacyUserReader.php
beta/app/Console/Commands/
  RbacSyncCommand.php
  RbacVerifyCommand.php

读侧:app/Foundation/Permission/Http/Middleware/PermissionMiddleware.php


同步阶段

幂等 upsert,可重复跑。

Phase输入输出
P0env / --fzx-idrbac_sync_runs
P1qx_list tie=0/1permissions 父子节点
P2本现场 qx.php + SHOW COLUMNS userspermissions 补全
P3users group='0'roles + role_permissions
P4users group!='0'user_roles
P5非 admin 用户user_permission_snapshots
P6menumenu_permissions

sync 不调 update_users_qx_by_group(),只读当前 users 列值。改组后现场顺序:组校正 → rbac-sync → rbac-verify


P2:权限目录与动态列

每个部署只有一份有效权限目录,不是把 gx_file/*_qx.php 全并进来。

来源处理
qx_list(tie=1, qx 非空)主来源
本现场 user_manage/qx.phpinclude 一次;若现场用 gx_file/{dw}_qx.php 覆盖,以 include 结果为准;source=php_catalog
SHOW COLUMNS FROM usersvarchar(1) 且在 qx 白名单或 qx_list 里

目录缺失列(users 有列、目录无定义):仍建 permissionsname=codeis_active=0is_catalog_missing=1;verify 报告列出,不删列;beta 不对其鉴权。

std_code:P1–P2 不写入,保持 NULL;仅 migration 建列,后期人工或 beta 管理页维护。

init_qx_list() 加了新列后跑 sync;报告里 new_permissions > 0 要留意。


verify 规则

#通过标准
VR1权限覆盖active 且 qx 非空的 code 全在 permissions
VR2组权限每个 role 的 role_permissions 记录集合 = 组行值为 1 的权限列集合
VR3用户权限抽样 N 个非 admin:user_permission_snapshots.has_permission = users.{qx}
VR3b组 union 审计same_as_role_permissions=0 写入报告(参考)
VR4菜单抽样 M 个 menu:算法 B = get_menu.php 主路径
VR5adminusers.admin=1 → superuser

VR4 第一版不覆盖:site_type 动态子项、shuju_tongji 分支、penetration_test()


什么时候可以开鉴权

sync + verify 阶段(路由还不拦):

  • migration 通过
  • 连续两次 sync 无增量
  • VR1–VR2 全过
  • VR3:≥50 用户 0 不一致
  • VR4:≥100 menu 不一致率 ≤1%

开 PermissionMiddleware:上面全过 + 单测 + RBAC_ENFORCE=true 试点 + 人工改组→sync→403/200。

开 MenuService 新规则:试点一周无 P0 + BETA_MENU_RBAC=true(可回滚)。

生产默认 enforce:改权限 SOP 含 sync;RBAC_FALLBACK_LEGACY_SESSION 必须 false。

以下情况先停:

  • legacy 有权限、user_permission_snapshots 无行
  • sync 后菜单可见项骤降 >5% 且无解释
  • 生产 enforce 但 >24h 未 sync

上线前

bash
cd beta
php artisan migrate --path=database/migrations/2026_xx_xx_create_rbac_tables.php
php artisan lims:rbac-sync --dry-run
php artisan lims:rbac-sync
php artisan lims:rbac-verify --sample-users=20 --sample-menus=50
php artisan test --filter=Rbac

人工:legacy 改组 → sync → beta 菜单对;无权限用户访问受保护路由 403。

常见坑:legacy 改权限 beta 滞后(改完跑 sync);menu token 解析错(用 BETA_MENU_RBAC 开关回滚);快照缺失会 silent deny(VR3 零容忍 + A4 日志)。