跳到主要内容
版本:3.10.x

API7 网关 AI Agent Skill:wolf-rbac 插件

概览

wolf-rbac 插件通过集成 Wolf RBAC 服务器 提供基于角色的访问控制(RBAC)。它支持集中认证,以及跨多个应用的基于 URL 和方法的细粒度权限检查,无需修改后端服务。

优先级: 2555(身份验证插件,在 rewrite 阶段运行)。

适用场景

  • 跨多个 HTTP 应用的集中式 RBAC
  • URL + HTTP 方法级别的权限控制
  • 面向微服务的统一用户管理
  • 需要登录、用户信息和修改密码 API 端点

前提条件

  1. Wolf RBAC 服务器 已运行(默认 http://127.0.0.1:12180
  2. 在 Wolf 控制台中配置:Application → Users → Roles → Permissions → Resources
  3. 通过 Docker 安装 Wolf:https://github.com/iGeeky/wolf/blob/master/quick-start-with-docker/README.md

插件配置参考(消费者)

字段类型是否必填默认值说明
serverstringhttp://127.0.0.1:12180Wolf RBAC 服务器 URL
appidstringunset在 Wolf 控制台中注册的应用 ID
header_prefixstringX-注入请求头的前缀(UserId、Username、Nickname)

注意: 请在消费者上配置该插件,而不是在路由上配置。路由配置应为空对象 {}

Token 格式

V1#<appid>#<wolf_jwt_token>

示例:V1#restful#eyJhbGciOiJIUzI1NiIs...

Token 提取优先级

  1. 查询参数:?rbac_token=V1%23app%23token(URL 编码)
  2. Authorization 请求头:Authorization: V1#app#token
  3. 自定义请求头:x-rbac-token: V1#app#token
  4. Cookie:x-rbac-token=V1#app#token

API 端点

该插件会注册三个端点(必须通过 public-api 插件暴露):

POST /apisix/plugin/wolf-rbac/login

认证并获取 rbac_token

请求:

{
"appid": "restful",
"username": "test",
"password": "user-password",
"authType": 1
}
  • authType1 = 密码(默认),2 = LDAP(Wolf v0.5.0+)

响应(200):

{
"rbac_token": "V1#restful#eyJhbGci...",
"user_info": {"id": "749", "username": "test", "nickname": "test"}
}

GET /apisix/plugin/wolf-rbac/user_info

获取已认证用户详情。需要有效的 rbac_token

响应(200):

{
"user_info": {
"id": 749,
"username": "test",
"nickname": "test",
"permissions": {"USER_LIST": true},
"roles": {}
}
}

PUT /apisix/plugin/wolf-rbac/change_pwd

修改密码。需要有效的 rbac_token

请求:

{"oldPassword": "old", "newPassword": "new"}

授权流程

1. 客户端携带 rbac_token 发送请求
2. API7 企业版解析 Token,并提取 appid 和 wolf_token。
3. 将 appid 与消费者配置进行匹配。
4. 调用 Wolf 服务器:GET /wolf/rbac/access_check
- appID, resName (URL), action (HTTP method), clientIP
5. Wolf 检查用户对该资源的角色和权限
6. 成功后注入 X-UserId、X-Username 和 X-Nickname 请求头。
7. 失败时返回 401(Token 无效)或 403(无权限)。

重试行为: 对 Wolf 服务器的 5xx 错误最多重试 3 次,每次间隔 100ms。

分步设置

1. 创建消费者

a7 consumer create -g default -f - <<'EOF'
{
"username": "wolf_rbac",
"plugins": {
"wolf-rbac": {
"server": "http://127.0.0.1:12180",
"appid": "restful"
}
}
}
EOF

2. 创建受保护路由

a7 route create -g default -f - <<'EOF'
{
"id": "protected-api",
"uri": "/api/*",
"plugins": {
"wolf-rbac": {}
},
"upstream": {
"type": "roundrobin",
"nodes": [{"host": "backend", "port": 8080, "weight": 1}]
}
}
EOF

3. 暴露登录端点

a7 route create -g default -f - <<'EOF'
{
"id": "wolf-login",
"uri": "/apisix/plugin/wolf-rbac/login",
"plugins": {
"public-api": {}
}
}
EOF

4. 暴露用户信息端点

a7 route create -g default -f - <<'EOF'
{
"id": "wolf-userinfo",
"uri": "/apisix/plugin/wolf-rbac/user_info",
"plugins": {
"public-api": {}
}
}
EOF

5. 暴露修改密码端点

a7 route create -g default -f - <<'EOF'
{
"id": "wolf-changepwd",
"uri": "/apisix/plugin/wolf-rbac/change_pwd",
"plugins": {
"public-api": {}
}
}
EOF

6. 测试登录

curl -X POST http://127.0.0.1:9080/apisix/plugin/wolf-rbac/login \
-H "Content-Type: application/json" \
-d '{"appid":"restful","username":"test","password":"user-password"}'

7. 访问受保护资源

curl http://127.0.0.1:9080/api/users \
-H "Authorization: V1#restful#<token_from_step_6>"

多应用设置

# 应用 1 消费者
a7 consumer create -g default -f - <<'EOF'
{
"username": "wolf_app1",
"plugins": {
"wolf-rbac": {
"server": "http://127.0.0.1:12180",
"appid": "app1"
}
}
}
EOF

# 应用 2 消费者
a7 consumer create -g default -f - <<'EOF'
{
"username": "wolf_app2",
"plugins": {
"wolf-rbac": {
"server": "http://127.0.0.1:12180",
"appid": "app2"
}
}
}
EOF

Token 中的每个 appid 都决定使用哪个消费者(以及哪个 Wolf 应用) 进行权限检查。

自定义请求头前缀

a7 consumer create -g default -f - <<'EOF'
{
"username": "wolf_custom",
"plugins": {
"wolf-rbac": {
"server": "http://127.0.0.1:12180",
"appid": "myapp",
"header_prefix": "Wolf-"
}
}
}
EOF

注入后的请求头为:Wolf-UserIdWolf-UsernameWolf-Nickname

配置同步示例

version: "1"
gateway_groups:
- name: default
consumers:
- username: wolf_rbac
plugins:
wolf-rbac:
server: "http://127.0.0.1:12180"
appid: restful
routes:
- id: protected-api
uri: /api/*
plugins:
wolf-rbac: {}
upstream:
type: roundrobin
nodes:
- host: api-backend
port: 8080
weight: 1
- id: wolf-login
uri: /apisix/plugin/wolf-rbac/login
plugins:
public-api: {}
- id: wolf-userinfo
uri: /apisix/plugin/wolf-rbac/user_info
plugins:
public-api: {}
- id: wolf-changepwd
uri: /apisix/plugin/wolf-rbac/change_pwd
plugins:
public-api: {}

注入的请求头

认证成功后,这些请求头会添加到请求 (上游)和响应(客户端)中:

请求头示例说明
{prefix}UserIdX-UserId: 749Wolf 用户 ID
{prefix}UsernameX-Username: adminWolf 用户名
{prefix}NicknameX-Nickname: administratorURL 编码的昵称

错误响应

状态码消息原因
401Missing rbac token in request任一受支持位置均未提供 Token
401invalid rbac token: parse failedToken 格式不是 V1#appid#jwt
401Invalid appid in rbac token没有 appid 匹配的消费者
401ERR_TOKEN_INVALIDJWT 已过期或签名无效
403ERR_ACCESS_DENIED用户缺少 URL + 方法权限
500request to wolf-server failedWolf 服务器不可达或发生错误

安全建议

  • 生产环境中为 Wolf 服务器 URL 使用 HTTPS
  • 优先使用 Authorization 请求头,而不是查询参数(避免 Token 被记录到日志)
  • 使用 Cookie 时设置 HttpOnlySecure 标志
  • 在登录端点结合 limit-req 防止暴力破解
  • 结合 ip-restriction 增加网络层安全性

故障排查

现象原因修复方式
登录时返回 400 "appid is missing"登录请求体缺少 appid包含 appid 字段
400 "appid not found"没有配置使用该 appid 的消费者创建 appid 匹配的消费者
每个请求都返回 401Token 已过期或传递位置不正确重新登录获取新 Token,并检查 Token 位置
403 "ERR_ACCESS_DENIED"用户在 Wolf 中没有对应 URL + 方法权限在 Wolf 控制台中配置权限
500 "request to wolf-server failed"Wolf 服务器停机或不可达检查 Wolf 服务器 URL 和连通性
登录端点返回 404未通过 public-api 暴露为登录 URI 创建启用 public-api 插件的路由

本页面由 api7/a7 仓库中的 a7-plugin-wolf-rbac/SKILL.md 生成。你可以在 AI Agent Skills 页面查看所有技能。