授权查询


什么是授权决策?

Speedle 在指定服务内评估主体、操作与资源,由应用执行结果。应区分评估错误、超时与正常的 Deny,并在出错时拒绝访问。REST、gRPC、嵌入式 Go 的数据表示不同,应分别遵循各自的 API 契约。

运行示例前

先按快速入门编译仓库根目录下的 ./bin/spctl、./bin/speedle-pms 和 ./bin/speedle-ads,需要 Go 1.26.10 或 Go 1.27.3(也可使用同一大版本的更新补丁版本)、Bash、curl 和 Python 3。下面各终端都从仓库根目录运行。为本页使用一个新的策略文件;仅在两个服务都停止后重建该文件。

初始化空策略文件:

printf '{}\n' > docs-policies.json

终端一启动 PMS,并保持运行:

./bin/speedle-pms --store-type file --filestore-loc ./docs-policies.json --endpoint 127.0.0.1:6733 --grpc-endpoint 127.0.0.1:0 --insecure=true

终端二启动 ADS,并保持运行:

./bin/speedle-ads --store-type file --filestore-loc ./docs-policies.json --endpoint 127.0.0.1:6734 --grpc-endpoint 127.0.0.1:0 --insecure=true

在第三个终端运行后续命令。PMS/ADS 共享同一个文件,策略更新通过 watch 异步到达 ADS;先查询确认已更新,再依赖新策略做决策。--insecure=true 仅用于回环地址上的本地示例,生产连接见安全配置。示例显式指定 PMS 地址,不修改 ~/.spctlconfig。完成后在两个服务终端按 Ctrl-C。

创建可重复的测试策略

测试文件给 Alan 分配 role1、role2;其中 role1 可以下载 /books/HarryPotter。

./bin/spctl --pms-endpoint http://127.0.0.1:6733/policy-mgmt/v1/ create service --json-file website/tests/examples/bookstore.json

获取授权决策

Alan 的请求允许;Bob 没有适用的允许策略,请求被拒绝。

curl --fail --silent --show-error -H 'Content-Type: application/json' \
  -d '{"subject":{"principals":[{"type":"user","name":"Alan"}]},"serviceName":"onlineBookStore","resource":"/books/HarryPotter","action":"download"}' \
  http://127.0.0.1:6734/authz-check/v1/is-allowed
curl --fail --silent --show-error -H 'Content-Type: application/json' \
  -d '{"subject":{"principals":[{"type":"user","name":"Bob"}]},"serviceName":"onlineBookStore","resource":"/books/HarryPotter","action":"download"}' \
  http://127.0.0.1:6734/authz-check/v1/is-allowed

成功评估返回 {"allowed":true,"reason":0} 或对应的 Deny 对象。HTTP 错误返回错误响应,不能视为成功授权。原因码如下:

数值 含义
0 GRANT_POLICY_FOUND
1 DENY_POLICY_FOUND
2 SERVICE_NOT_FOUND
3 NO_APPLICABLE_POLICIES
4 ERROR_IN_EVALUATION
5 DISCOVER_MODE
6 REASON_NOT_AVAILABLE

DISCOVER_MODE 不表示生产授权通过;REASON_NOT_AVAILABLE 是回退原因值。这些数值不是 HTTP 状态码。

查询已授予角色

curl --fail --silent --show-error -H 'Content-Type: application/json' \
  -d '{"subject":{"principals":[{"type":"user","name":"Alan"}]},"serviceName":"onlineBookStore","resource":"/books/HarryPotter","action":"download"}' \
  http://127.0.0.1:6734/authz-check/v1/all-granted-roles

预期包含 role1、role2,顺序无意义。查询有资源范围的角色分配时,需要传入对应的 resource。

查询已授予权限

curl --fail --silent --show-error -H 'Content-Type: application/json' \
  -d '{"subject":{"principals":[{"type":"user","name":"Alan"}]},"serviceName":"onlineBookStore","resource":"/books/HarryPotter","action":"download"}' \
  http://127.0.0.1:6734/authz-check/v1/all-granted-permissions

预期权限为资源 /books/HarryPotter 上的 download 操作。此接口列出已授予权限;执行具体业务操作仍应调用 is-allowed,不能用权限列表代替完整的请求评估。

属性、诊断与令牌身份

REST 请求属性是带类型的对象数组。例如,其中一个属性对象为:

{
  "name": "clearance",
  "type": "numeric",
  "value": 4
}

嵌入式 Go 使用 map[string]interface{}。诊断响应的属性也是对象,不能与请求属性数组混淆。属性类型与条件见 SPDL,过程明细见授权诊断,令牌校验见令牌断言。