跳到主要内容

wolf-rbac

wolf-rbac 插件将 APISIX 和 API7 网关与 Wolf 的基于角色的访问控制集成。插件从调用方的 RBAC Token 中读取 Wolf 应用 ID,选择匹配的网关消费者,然后向 Wolf 查询该用户是否有权在请求 URI 上执行对应的请求方法。

RBAC Token 选中有效消费者后,插件会移除客户端在这些身份头字段中提供的值。Wolf 返回用户信息时,网关会将已验证用户的 ID、用户名和昵称加入返回客户端的响应。对于获准的请求,还会将这些值转发到上游。使用默认前缀时,这些头字段为 X-UserId、X-Username 和 X-Nickname。

示例​

以下使用一条受保护的 HTTPBin 路由,展示网关如何处理未认证、被拒绝和获准的请求。

使用 Wolf RBAC 授权请求​

网关必须正在运行,并且能够访问 Wolf 服务器。

设置 Wolf​

可以使用现有 Wolf 部署,其中应有一个应用及用户,其策略允许 GET / 并拒绝 POST /。如需本地演示环境,请安装 Docker 和 Git,然后克隆 Wolf 仓库并检出 0.8.0 版本:

git clone https://github.com/iGeeky/wolf.git
cd wolf
git checkout --detach 0.8.0
cd quick-start-with-docker

创建 docker-compose.docs.yaml,使用已检出的 0.8.0 源码在本地构建 Wolf 服务器:

docker-compose.docs.yaml
services:
server:
image: wolf-server-docs:0.8.0
build:
context: ../server

启动 Wolf 数据库、缓存及从源码构建的服务器:

docker compose \
-f docker-compose.yaml \
-f docker-compose.docs.yaml \
up -d --build database cache server

等待 Wolf 服务器可以接受请求:

until curl --max-time 2 -fsS "http://127.0.0.1:12180/wolf/ping" > /dev/null; do
sleep 1
done

初始化 Wolf 的演示应用,并为这些应用的用户设置相同的本地测试密码:

sh wolf-demo-init.sh wolf-test-password

初始化会创建 restful-demo 应用,并授予其 app-man 用户向 / 发送 GET 请求的权限。演示环境的更多说明,请参阅 Wolf 0.8.0 Docker 快速入门。

快速入门中的凭据和密钥仅用于本地测试。对于任何非测试环境,请生成唯一密钥,并遵循 Wolf 项目的部署指南。

导出应用 ID 和用户凭据。以下值与本地演示环境相符;使用现有部署时,请替换为对应的值:

export WOLF_APP_ID="restful-demo"
export WOLF_USERNAME="app-man"
export WOLF_PASSWORD="wolf-test-password"

将 WOLF_SERVER 设置为网关可以访问的 Wolf 源站地址。必须包含 http:// 或 https:// 协议前缀,且末尾不能有斜杠:

export WOLF_SERVER="YOUR_GATEWAY_REACHABLE_WOLF_URL"

仅在可信测试网络中使用 HTTP。生产环境中,请使用 HTTPS,并按照通过 HTTPS 连接 Wolf 的说明启用证书验证。

配置消费者和路由​

将 ADMIN_API_KEY 设置为网关的 Admin API 密钥。以下命令使用默认的本地 Admin API 地址和代理地址;请将其替换为实际部署的地址。

为 Wolf 应用创建消费者:

curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d @- <<EOF
{
"username": "wolf-consumer",
"plugins": {
"wolf-rbac": {
"appid": "${WOLF_APP_ID}",
"server": "${WOLF_SERVER}",
"header_prefix": "X-Wolf-"
}
}
}
EOF

❶ appid:与 RBAC Token 中的应用 ID 匹配时,选中此消费者。

❷ server:设置网关向 Wolf 发起请求时使用的 Wolf 源站地址。

❸ header_prefix:将承载已验证身份的头字段改为 X-Wolf-UserId、X-Wolf-Username 和 X-Wolf-Nickname。

创建接受 GET 和 POST 请求的受保护路由。使用空插件配置启用 wolf-rbac,并在将请求转发到 HTTPBin 前移除请求中的 RBAC Token:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "wolf-rbac-route",
"uri": "/",
"methods": ["GET", "POST"],
"plugins": {
"wolf-rbac": {},
"proxy-rewrite": {
"headers": {
"remove": ["Authorization"]
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'

❶ wolf-rbac:根据 Wolf 中授予用户的权限,检查请求方法和 URI。连接设置来自 RBAC Token 选中的消费者。

❷ proxy-rewrite:在授权后执行,并在请求发送到上游前移除本示例使用的 Authorization 请求头。

创建单独的路由来暴露插件的登录端点。此路由只配置 public-api,使尚无 RBAC Token 的调用方也能登录:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "wolf-rbac-login",
"uri": "/apisix/plugin/wolf-rbac/login",
"plugins": {
"public-api": {}
}
}'

验证访问​

发送不带 RBAC Token 的请求:

curl -i "http://127.0.0.1:9080/"

网关会以 HTTP/1.1 401 Unauthorized 拒绝请求:

{"message":"Missing rbac token in request"}

使用 jq 通过已暴露的 Wolf 端点登录,并保存返回的 RBAC Token。只有响应包含非空字符串时,才会导出该 Token:

RBAC_TOKEN="$(
jq -n \
--arg appid "${WOLF_APP_ID}" \
--arg username "${WOLF_USERNAME}" \
--arg password "${WOLF_PASSWORD}" \
'{appid: $appid, username: $username, password: $password}' | \
curl -sS "http://127.0.0.1:9080/apisix/plugin/wolf-rbac/login" \
-H 'Content-Type: application/json' \
-d @- | \
jq -er '.rbac_token | select(type == "string" and length > 0)'
)" &&
export RBAC_TOKEN

发送 POST 请求,在 Authorization 请求头中原样传入 RBAC Token,不要添加 Bearer 前缀:

curl -i "http://127.0.0.1:9080/" -X POST \
-H "Authorization: ${RBAC_TOKEN}"

本地演示环境授予 app-man 向 / 发送 GET 请求的权限,但不允许 POST 请求。因此,Wolf 会以 HTTP/1.1 403 Forbidden 拒绝请求。

发送获准的 GET 请求:

curl -i "http://127.0.0.1:9080/" \
-H "Authorization: ${RBAC_TOKEN}"

应收到 HTTP/1.1 200 OK 响应,并包含 X-Wolf-UserId、X-Wolf-Username 和 X-Wolf-Nickname 响应头。

插件也接受通过 x-rbac-token 请求头、rbac_token 查询参数或 x-rbac-token Cookie 传入 RBAC Token。

wolf-rbac 本身不会从请求中移除用于传入 RBAC Token 的值。上述路由通过 proxy-rewrite 移除 Authorization 请求头。如果客户端使用其他传入方式,也应防止对应的请求头、查询参数或 Cookie 被发送到上游。

通过 HTTPS 连接 Wolf​

生产环境中,请配置 HTTPS Wolf 地址,并将消费者上的 ssl_verify 设置为 true。这样,网关会在用户登录和权限检查时验证 Wolf 服务器证书:

{
"wolf-rbac": {
"appid": "restful-demo",
"server": "https://wolf.internal.example",
"header_prefix": "X-Wolf-",
"ssl_verify": true
}
}

省略 ssl_verify 或将其设置为 false 时,网关不会验证 Wolf 服务器证书。

API 端点​

插件会注册以下内部端点。请通过配置了 public-api 插件的路由,仅暴露客户端所需的端点。

方法端点用途
POST/apisix/plugin/wolf-rbac/login认证 Wolf 用户并返回 rbac_token。
PUT/apisix/plugin/wolf-rbac/change_pwd更改已认证 Wolf 用户的密码。
GET/apisix/plugin/wolf-rbac/user_info返回已认证 Wolf 用户的信息。

更改密码和查询用户信息的端点需要有效的 RBAC Token。消费者字段和默认值请参阅 wolf-rbac 配置参考。