GrantForgeDocs

    技术文档

    权限模型

    资源、授权推导、继承、分配、数据与字段规则的精确语义,以及权限快照与版本。

    本文描述求值的精确规则。概念入门见 核心概念。

    资源树与类型

    资源属于某个应用,按树组织,最多 15 层。类型决定能放在哪里:

    类型 允许的父级
    模块 顶级、模块
    菜单、页面 顶级、模块、菜单
    标签 页面、标签
    按钮 页面、标签
    API、数据实体 顶级、模块
    字段 数据实体

    资源之间可以声明依赖:“必需”(授予资源时一并授予被依赖的资源)或“可选”(只提示管理员,不自动授予);依赖不能成环。控制台的页面、按钮与它们需要的 API 由前端的权限清单声明,服务端启动时同步为内置资源。

    授权推导

    对一个账号,求值器先确定有效角色:

    1. 直接分配给账号的角色;
    2. 分配给账号所在用户组、部门(包含“含下级”的上级部门分配)、所任岗位的角色;
    3. 只取当前时间在有效期内的分配,以及已启用的角色;
    4. 展开继承:一个角色的全部祖先角色(停用的祖先不传递)。

    再合并这些角色的授权:

    • 允许一个资源,等于允许它本身、它在树上的祖先(使其可见),以及它“必需”依赖的资源(递归)。
    • 拒绝一个资源,作用于它和它的全部下级,并且优先于任何允许。
    • 停用的资源及其下级不生效。
    • 系统角色等同于允许其模块(如 system、data、platform)的整棵子树。

    结果是可用资源的集合,以及其中 API 资源对应的权限码。

    越权防护

    • 授予“允许”时,授予者自己必须能用该资源(持有系统角色的人对业务应用不受此限)。
    • 分配角色或设置继承时,授予者必须覆盖该角色在各应用中覆盖的全部资源。
    • 平台管理员角色只能由当前持有者分配、修改或移除。
    • “拒绝”不受限制:任何有授权权限的人都可以收紧权限。

    数据规则

    数据策略属于角色,按“实体 × 动作 × 效果”定义范围:ALL(仅平台租户)、TENANT、ORG_AND_CHILDREN、ORG、CUSTOM_ORGS、SELF、CONDITION。一行可用,当且仅当它满足至少一条允许规则,且不满足任何拒绝规则。

    条件是结构化 JSON,不可执行,先校验再落库:

    { "and": [
      { "field": "status", "op": "eq", "value": "ACTIVE" },
      { "not": { "field": "orgUnitId", "op": "in", "value": { "var": "subject.orgUnitIds" } } }
    ] }

    变量只有 subject.id、subject.username、subject.orgUnitIds、subject.groupCodes、subject.positionCodes 与 now;比较符按字段类型限定;嵌套不超过 5 层、节点不超过 50 个。服务端把规则翻译成 JPA Specification,SDK 用同样的语义在业务应用里翻译。

    字段规则

    字段策略给出读方式(可见、脱敏、隐藏)与写方式(可编辑、只读),多个角色取最宽松的设置,没有任何设置时字段完全开放。读规则在 JSON 序列化时执行(同一个 DTO 在不同人面前呈现不同),写规则在服务层执行,修改只读字段返回 GF-FIELD-001 并指出字段。

    快照与版本

    求值结果是一个权限快照:可用资源、权限码、数据规则与字段规则。快照按账号缓存;授权、分配、继承、资源目录、策略、成员关系的任何变化都会提升所在范围(目录或租户)的版本号,使缓存失效。每个需要权限的接口在响应头 X-Authorization-Version 中返回当前版本,控制台据此判断是否需要重新加载菜单;开放 API 用 ETag 表达同样的版本。

    在 GitHub 上编辑此页