3. 加上权限

页面能打开后,再确定每个人能看到什么。这个案例使用两个权限集:教程业务员和教程主管。

操作业务员主管
进入教程订单列表和详情允许允许
查看订单仅自己的订单全部订单
创建订单允许,归属当前用户允许,归属当前用户
提交审批仅自己的草稿或已驳回订单仅自己的草稿或已驳回订单
通过、驳回、补发结果不允许允许

客户在本练习中是所有业务员可读取的公共资料,客户维护交给管理员。主管审批也不能绕过订单状态检查。

本章目标与起点

上一章的列表和详情已经接上数据库。本章准备不同账号,把“能打开页面”“能执行操作”“能访问哪些记录”分别检查清楚。

三类权限分别控制什么

层次订单示例检查方式
页面访问是否可以进入教程订单从菜单进入并直接打开地址
操作权限是否可以通过或驳回订单检查按钮和直接接口请求
数据范围是否只能看到自己的订单甲、乙分别创建数据并交换详情地址

权限集把一组授权放在一起,便于分配给多个用户。订单归属来自 ownerId,与当前登录用户的 ID 对应;同一个“业务员”权限集因此可以让甲和乙各自访问不同的记录。

接入权限能力

读取当前应用的 Authorization Skill 和 Users Skill,为教程订单接入现有权限系统,不另建角色表。

注册 tutorialOrders 集合及 read、create、update 动作,字段元数据由数据库提供,归属使用 ownerId。分别注册列表/详情页面与查看、提交、通过、驳回等业务操作,并声明每个操作可使用的字段。

创建“教程业务员”和“教程主管”权限集。业务员 read/update 使用 recordsIOwn,主管使用 allRecords;只允许需要的输入和输出字段。创建时 ownerId 来自登录身份。

业务操作在请求级 authorize() 中检查一次,将 conditions.database 的策略通过 repository.withPolicy() 绑定到对应查询和写入。普通集合 CRUD 使用 db.policyFor()。不能只隐藏菜单和按钮,也不能先查询全部数据再在浏览器中过滤。

为后续审批保留主管操作权限;提交接口还要检查本人归属。前端按权限展示操作,服务端独立校验。

完整的职责设计流程见向 AI 描述业务权限。

应用代码使用的数据库资源 ID 是 tutorialOrders。权限集配置、页面资源名和接口中的检查必须对应;不要用可见的中文标题代替资源 ID。

创建测试账号

管理员打开“设置 → 用户管理”,创建业务员甲、业务员乙、销售主管三个账号,再分配对应角色。使用你自己设定的测试密码,不使用管理员账号代替业务员。

用户管理中的业务员甲、业务员乙和销售主管及其角色

换账号验证

业务员甲登录后创建 SO-A01,业务员乙创建 SO-B01。两人各自只应看到自己的订单,主管应看到两张。

把甲的详情地址复制到乙的浏览器中,乙不能读取内容。请 AI Agent 再检查直接调用接口的结果:匿名读取应返回 401;不允许的操作应被拒绝;不属于当前数据范围的详情不应返回订单内容。

在下一章继续验证业务员伪造审批请求也会失败。单纯隐藏“通过”按钮不足以保护订单。

下一步:接一条审批流。