Skip to content

简单模式 ​

面向要为一个服务、一个客户提供保护的开发者,或不需要应用、空间和业务动作名称的小型产品。简单模式是能运行的最小配置:一份平台文档,请求用 HTTP 方法和路径命名,不用路由映射。本页列出需要什么,给出一份可用的文档,并说明何时该往前走。

你需要什么 ​

简单模式
依赖快速开始里的那些
配置spring.data.redis.* 和 cosec.jwt.secret。客户端直连服务时再加 cosec.authorization.remote-ip.max-trusted-index: 0。应用、空间、路由映射都不用配。
文件platform.json;用 cosec-migrate publish 写成第一个修订
Redismaxmemory-policy noeviction
概念平台文档、策略、语句、绑定给所有人("subject": "*")、http 命名空间、默认拒绝、拒绝优先、默认租户 (0)
可以省掉应用和空间、路由映射、目录、角色条目、边界、限流、影子窗口

每个请求都是 http:path:<path> 上的 http:<METHOD>。令牌不带租户,所以主体在默认租户 (0);不带应用,所以不读取任何应用文档。

文档 ​

json
{
  "schema": 2,
  "revision": 1,
  "publishedAt": "2026-11-01T08:00:00Z",
  "policies": [
    {
      "id": "login",
      "statements": [
        {
          "name": "login",
          "effect": "allow",
          "action": "http:POST",
          "resource": "http:path:/auth/login"
        }
      ]
    },
    {
      "id": "control-api",
      "statements": [
        {
          "name": "reach-the-control-api",
          "effect": "allow",
          "action": [
            "http:GET",
            "http:POST",
            "http:DELETE"
          ],
          "resource": "http:path:/cosec/control/v1/**",
          "condition": {
            "eq": [
              "subject.authenticated",
              true
            ]
          }
        }
      ]
    },
    {
      "id": "public",
      "statements": [
        {
          "name": "hello",
          "effect": "allow",
          "action": "http:GET",
          "resource": "http:path:/hello"
        }
      ]
    },
    {
      "id": "members",
      "statements": [
        {
          "name": "read-orders",
          "effect": "allow",
          "action": "http:GET",
          "resource": "http:path:/orders/**",
          "condition": {
            "eq": [
              "subject.authenticated",
              true
            ]
          }
        }
      ]
    },
    {
      "id": "admins",
      "statements": [
        {
          "name": "admin-area",
          "effect": "allow",
          "action": "http:*",
          "resource": "http:path:/admin/**",
          "condition": {
            "in": [
              "admin",
              "scope.roles"
            ]
          }
        }
      ]
    },
    {
      "id": "no-delete",
      "statements": [
        {
          "name": "orders-are-kept",
          "effect": "deny",
          "action": "http:DELETE",
          "resource": "http:path:/orders/**"
        }
      ]
    }
  ],
  "bindings": [
    {
      "id": "login",
      "subject": "*",
      "app": "*",
      "space": "*",
      "policy": "login"
    },
    {
      "id": "control-api",
      "subject": "*",
      "app": "*",
      "space": "*",
      "policy": "control-api"
    },
    {
      "id": "public",
      "subject": "*",
      "app": "*",
      "space": "*",
      "policy": "public"
    },
    {
      "id": "members",
      "subject": "*",
      "app": "*",
      "space": "*",
      "policy": "members"
    },
    {
      "id": "admins",
      "subject": "*",
      "app": "*",
      "space": "*",
      "policy": "admins"
    },
    {
      "id": "no-delete",
      "subject": "*",
      "app": "*",
      "space": "*",
      "policy": "no-delete"
    }
  ]
}
  • public 允许任何人 GET /hello,无论是否登录;login 对 POST /auth/login 同理。
  • members 允许已登录的调用方 GET /orders/**。
  • admins 允许持有角色 admin 的主体访问 /admin/** 下的一切。简单模式里令牌的角色是默认空间的角色,所以 scope.roles 就是令牌的 roles 声明。授权请用 scope.roles,不要用 subject.roles,后者也会计入其他空间里的角色(条件中的角色)。
  • no-delete 对所有人禁止 DELETE /orders/**。匹配的 DENY 胜过所有 ALLOW,admin 也不例外。
  • control-api 允许任何已登录的调用方到达控制 API 的路径。控制面会以调用方的身份再授权每一步,所以这里开放的是路径,不是权限。没有它,你就再也无法通过控制面修改这份文档,见之后修改文档。

用户登录时签发带角色的令牌:

kotlin
TokenSubject(id = user.id, app = null, roles = setOf("admin"))

验证 ​

wiki/examples/simple/scenarios 里的场景在每次构建时用测试套件对这些文档运行:

请求调用方决策
GET /hello匿名Permit
GET /orders/1匿名Deny:401
GET /orders/1已登录Permit
DELETE /orders/1角色 adminDeny:DENY 获胜
GET /admin/users角色 adminPermit
GET /admin/users已登录,无角色Deny:403

很多角色 ​

每个角色一个条件,超过几个就不好用了。默认租户和其他租户一样,可以放角色绑定:在平台文档里不绑定 admins,把绑定放进 tenants/(0).json(文件名要做 URL 编码,即 tenants/%280%29.json):

json
{
  "schema": 2,
  "revision": 1,
  "publishedAt": "2026-11-01T08:00:00Z",
  "bindings": [
    {
      "id": "editors-edit",
      "subject": {
        "role": "editor"
      },
      "app": "*",
      "space": "*",
      "policy": "editors"
    },
    {
      "id": "admins-administer",
      "subject": {
        "role": "admin"
      },
      "app": "*",
      "space": "*",
      "policy": "admins"
    }
  ]
}

这里的角色绑定适用于持有该角色的主体;而这份文档里绑定给 "*" 的内容也适用于匿名调用方,因为它们同样属于 (0)。包含平台文档和场景的完整示例见 wiki/examples/simple-roles。

简单模式的限制 ​

  • 平台文档不能绑定角色。它由所有租户共用,写在那里的角色对所有租户意味着同一件事。请用上面的条件,或 (0) 文档。
  • 角色变更在用户下次登录时才生效,因为角色在令牌里(角色与空间)。
  • 权限写成语句。想在控制台里列出权限、或按名称把权限授予角色,请换成应用文档:不使用空间的应用。

**下一步:**带权限和角色的应用,见不使用空间的应用。

基于 Apache License 2.0 发布