项目、区域与物模型数据权限
约 1221 字大约 4 分钟
2025-03-03
接口动作权限决定“能不能调用”,项目、区域和物模型权限决定“能操作哪些数据”。平台扩展接口时必须复用当前授权资源,不能仅看项目请求头或沿用旧的 UserCtx 字段结构。
当前资源模型
认证链加载资源提供者结果,Things 通过 dataType.GetProjectResource(userCtx) 取得项目授权。该助手可处理 RPC 传输后还原的 map,业务不要自行强转未经检查的资源对象。
项目资源包含项目权限、指定区域权限和区域路径权限。常用助手位于 things/share/dataType/helpers.go:
| 方法 | 用途 |
|---|---|
GetProjectResource | 获取并还原项目资源 |
HasProjectAccess | 检查项目是否在可访问范围 |
GetAreaIDs / GetAreaPaths | 取得区域筛选信息 |
GetAreaAuthType | 计算目标区域的有效操作级别 |
HasProjectAccess 用于项目范围判断,不能单独替代读写级别和物模型授权。
权限等级
| 值 | 常量 | 含义 |
|---|---|---|
| 1 | def.AuthAdmin | 管理 |
| 2 | def.AuthReadWrite | 读写 |
| 3 | def.AuthRead | 只读 |
| 4 | def.AuthNone | 无权 |
数值越小权限越高。需要读写时,有效级别必须满足 AuthReadWrite;不能用 >= 把只读误认为更高权限。未知值和缺失资源应按调用入口做拒绝/规范化,不能当成管理员。
区域权限优先级
当前 GetAreaAuthType 的顺序是:
- 缺少用户身份返回无权;管理员/拥有者按现有入口处理。
- 缺少项目资源或项目明确无权时返回无权。
- 命中精确区域 ID 权限则使用该项。
- 否则选择最长匹配的区域路径权限。
- 未命中区域项时使用项目默认权限。
当前实现没有把所有区域权限强制压到项目默认级别以内。例如项目默认只读而某个区域明确读写时,该区域可得到读写;不要同时在文档写“区域可单独授权”和“项目默认权限永远是上限”。新增授权能力时,先明确是否保持这一行为并验证兼容。
读写设备时的检查顺序
可信身份 → 设备所属企业 → 项目/分享访问 → 区域读写级别 → 物模型权限 → 仓储操作设备不是当前请求项目的,仅替换 project-id 头不能使其合法。设备实际 ProjectID、AreaID 与路径应来自已验证的设备记录,不能使用请求体自报的归属绕过检查。
设备分享是独立授权来源。无项目访问时,当前设备授权入口还可能检查分享用户及 SchemaPerm;不要复制一半逻辑漏掉分享或字段约束。
物模型权限
Things 内部设备操作使用 SchemaAccess 等现有入口检查控制参数,并按项目、区域或分享权限计算可操作字段。该入口依赖 dmsvr 的 ServiceContext,属于服务内部业务逻辑,不是可由外部应用导入的公共 SDK。
- 只读权限不能控制属性。
- 批量控制逐个验证目标设备,不能只检查第一台。
- 数组/结构字段按现有物模型路径规则归一化。
- 返回的过滤参数要被实际下发使用,不能校验后又使用未过滤原始数据。
独立应用通过平台受保护接口操作设备;自有业务数据还需实现自己的企业/项目隔离。
列表和详情一致
列表按授权项目/区域过滤,详情、更新和删除也检查同样范围。统计查询、导出、后台任务、WebSocket 订阅和 Hook 回调不能成为绕过详情权限的另一条通道。
后台任务按记录所属企业处理;缓存键包含业务范围。权限变更后验证缓存失效和实时订阅收敛,不以菜单消失作为撤权完成的证据。
验证矩阵
| 场景 | 预期 |
|---|---|
| 项目默认只读,无区域覆盖 | 可读,禁止控制 |
| 项目默认只读,区域明确读写 | 该区域按现有优先级可写 |
| 区域路径和精确 ID 均命中 | 精确 ID 优先 |
| 多个路径命中 | 最长匹配优先 |
| 项目无访问且无分享 | 拒绝 |
| 分享仅允许部分字段 | 控制不得超出字段范围 |
| 企业不匹配 | 不能因同 ID 或同项目头放行 |
| RPC 后资源转为 map | 统一助手还原后结果一致 |
涉及对外合同修改时,保持数字/字符串 ID、嵌套权限字段与 apilegacy 行为一致,按合同维护验证。
更新日志
2026/10/16 19:46
查看所有更新日志
b3b4d-docs(平台开发): 恢复有效专题并更新当前实现示例于
