Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions apisix/plugins/multi-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ function _M.rewrite(conf, ctx)
local status_code
local errors = {}

for _, auth_plugin in pairs(auth_plugins) do
for auth_plugin_name, auth_plugin_conf in pairs(auth_plugin) do
local auth = plugin.get(auth_plugin_name)
if auth.clear_auth_headers then
auth.clear_auth_headers(auth_plugin_conf, ctx)
end
end
end

for k, auth_plugin in pairs(auth_plugins) do
for auth_plugin_name, auth_plugin_conf in pairs(auth_plugin) do
local auth = plugin.get(auth_plugin_name)
Expand Down
70 changes: 50 additions & 20 deletions apisix/plugins/wolf-rbac.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ local sleep = core.sleep
local ngx_re = require("ngx.re")
local http = require("resty.http")
local ngx = ngx
local ipairs = ipairs
local rawget = rawget
local rawset = rawset
local setmetatable = setmetatable
Expand All @@ -31,27 +32,34 @@ local req_read_body = ngx.req.read_body
local req_get_body_data = ngx.req.get_body_data

local plugin_name = "wolf-rbac"
local default_header_prefix = "X-"


local schema = {
type = "object",
properties = {
header_prefix = {
type = "string",
default = default_header_prefix
},
}
}

local consumer_schema = {
type = "object",
properties = {
appid = {
type = "string",
default = "unset"
},
server = {
type = "string",
default = "http://127.0.0.1:12180"
},
header_prefix = {
type = "string",
default = "X-"
},
ssl_verify = {
type = "boolean",
},
}
},
required = {"appid"},
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After this move, leftover Consumer keys server / header_prefix / ssl_verify still validate (JSON Schema allows extra properties by default) but are ignored at runtime — traffic can silently hit the default http://127.0.0.1:12180.

Please fail loud on TYPE_CONSUMER: reject those three fields in check_schema (clearer than only additionalProperties = false, and matches an intentional migration), and add a negative Admin/schema test next to the existing “appid is required” case.


local _M = {
Expand All @@ -60,10 +68,21 @@ local _M = {
type = 'auth',
name = plugin_name,
schema = schema,
consumer_schema = consumer_schema,
}


local token_version = 'V1'
local identity_headers = {"UserId", "Username", "Nickname"}


function _M.clear_auth_headers(conf, ctx)
for _, name in ipairs(identity_headers) do
core.request.set_header(ctx, conf.header_prefix .. name, nil)
end
end


local function create_rbac_token(appid, wolf_token)
return token_version .. "#" .. appid .. "#" .. wolf_token
end
Expand Down Expand Up @@ -142,8 +161,19 @@ local function http_get(uri, myheaders, timeout, ssl_verify)
end


function _M.check_schema(conf)
local ok, err = core.schema.check(schema, conf)
function _M.check_schema(conf, schema_type)
if schema_type ~= core.schema.TYPE_CONSUMER then
return core.schema.check(schema, conf)
end

-- the old schema stored the default "X-" on every consumer
if conf.header_prefix ~= nil and conf.header_prefix ~= default_header_prefix then
return false, "header_prefix is no longer supported in consumer configuration, "
.. "move it to the route or service wolf-rbac configuration"
end
conf.header_prefix = nil

local ok, err = core.schema.check(consumer_schema, conf)
if not ok then
return false, err
end
Expand Down Expand Up @@ -239,6 +269,8 @@ end


function _M.rewrite(conf, ctx)
_M.clear_auth_headers(conf, ctx)

local url = ctx.var.uri
local action = ctx.var.request_method
local client_ip = core.request.get_remote_client_ip(ctx)
Expand Down Expand Up @@ -287,23 +319,11 @@ function _M.rewrite(conf, ctx)

local username = nil
local nickname = nil
local prefix = cur_consumer.auth_conf.header_prefix or ''
-- drop client-supplied identity headers before trusting the auth response
core.request.set_header(ctx, prefix .. "UserId", nil)
core.request.set_header(ctx, prefix .. "Username", nil)
core.request.set_header(ctx, prefix .. "Nickname", nil)
if type(res.userInfo) == 'table' then
local userInfo = res.userInfo
ctx.userInfo = userInfo
local userId = userInfo.id
username = userInfo.username
nickname = userInfo.nickname or userInfo.username
core.response.set_header(prefix .. "UserId", userId)
core.response.set_header(prefix .. "Username", username)
core.response.set_header(prefix .. "Nickname", ngx.escape_uri(nickname))
core.request.set_header(ctx, prefix .. "UserId", userId)
core.request.set_header(ctx, prefix .. "Username", username)
core.request.set_header(ctx, prefix .. "Nickname", ngx.escape_uri(nickname))
end

if res.status ~= 200 then
Expand All @@ -312,6 +332,16 @@ function _M.rewrite(conf, ctx)
") failed, res status: ", res.status, ", err: ", res.err)
return res.status, fail_response(res.err, { username = username, nickname = nickname })
end
if type(res.userInfo) == 'table' then
local prefix = conf.header_prefix
local userId = res.userInfo.id
core.response.set_header(prefix .. "UserId", userId)
core.response.set_header(prefix .. "Username", username)
core.response.set_header(prefix .. "Nickname", ngx.escape_uri(nickname))
core.request.set_header(ctx, prefix .. "UserId", userId)
core.request.set_header(ctx, prefix .. "Username", username)
core.request.set_header(ctx, prefix .. "Nickname", ngx.escape_uri(nickname))
end
consumer.attach_consumer(ctx, cur_consumer, consumer_conf)
core.log.info("wolf-rbac check permission passed")
end
Expand Down
22 changes: 17 additions & 5 deletions docs/en/latest/plugins/wolf-rbac.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,19 @@ The `wolf-rbac` Plugin provides a [role-based access control](https://en.wikiped

## Attributes

| Name | Type | Required | Default | Description |
|---------------|--------|----------|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| server | string | False | "http://127.0.0.1:12180" | Service address of wolf server. |
| appid | string | False | "unset" | App id added in wolf console. This field supports saving the value in Secret Manager using the [APISIX Secret](../terminology/secret.md) resource. |
| header_prefix | string | False | "X-" | Prefix for a custom HTTP header. After authentication is successful, three headers will be added to the request header (for backend) and response header (for frontend) namely: `X-UserId`, `X-Username`, and `X-Nickname`. |
### Consumer

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| appid | string | True | | App id added in wolf console. This field supports saving the value in Secret Manager using the [APISIX Secret](../terminology/secret.md) resource. |
| server | string | False | "http://127.0.0.1:12180" | Service address of wolf server. |
| ssl_verify | boolean | False | false | If true, verify the TLS certificate of the wolf server. |

### Route or Service

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| header_prefix | string | False | "X-" | Prefix for the identity headers. After authentication is successful, three headers will be added to the request header (for backend) and response header (for frontend) namely: `{prefix}UserId`, `{prefix}Username`, and `{prefix}Nickname`. Client-supplied headers with these names are removed before authentication. |

## API

Expand Down Expand Up @@ -114,6 +122,10 @@ curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X

You can also use the [APISIX Dashboard](/docs/dashboard/USER_GUIDE) to complete the operation through a web UI.

## Upgrade

`header_prefix` is configured on the Route or Service and is no longer accepted on the Consumer. Before upgrading, move a custom `header_prefix` from each Consumer to every Route or Service that uses `wolf-rbac`, including `wolf-rbac` configured inside `multi-auth`, and remove it from the Consumer. A Consumer that still sets a value other than the default `"X-"` fails validation. `appid`, `server`, and `ssl_verify` stay on the Consumer.

<!--
![add a consumer](https://raw.githubusercontent.com/apache/apisix/master/docs/assets/images/plugin/wolf-rbac-1.png)

Expand Down
22 changes: 17 additions & 5 deletions docs/zh/latest/plugins/wolf-rbac.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,19 @@ description: 本文介绍了关于 Apache APISIX `wolf-rbac` 插件的基本信

## 属性

| 名称 | 类型 | 必选项 | 默认值 | 描述 |
| ------------- | ------ | ------ | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| server | string | 否 | "http://127.0.0.1:12180" | `wolf-server` 的服务地址。 |
| appid | string | 否 | "unset" | 在 `wolf-console` 中已经添加的应用 id。该字段支持使用 [APISIX Secret](../terminology/secret.md) 资源,将值保存在 Secret Manager 中。 |
| header_prefix | string | 否 | "X-" | 自定义 HTTP 头的前缀。`wolf-rbac` 在鉴权成功后,会在请求头 (用于传给后端) 及响应头 (用于传给前端) 中添加 3 个 header:`X-UserId`, `X-Username`, `X-Nickname`。|
### Consumer

| 名称 | 类型 | 必选项 | 默认值 | 描述 |
| --- | --- | --- | --- | --- |
| appid | string | 是 | | 在 `wolf-console` 中已经添加的应用 id。该字段支持使用 [APISIX Secret](../terminology/secret.md) 资源,将值保存在 Secret Manager 中。 |
| server | string | 否 | "http://127.0.0.1:12180" | `wolf-server` 的服务地址。 |
| ssl_verify | boolean | 否 | false | 为 true 时,验证 `wolf-server` 的 TLS 证书。 |

### Route 或 Service

| 名称 | 类型 | 必选项 | 默认值 | 描述 |
| --- | --- | --- | --- | --- |
| header_prefix | string | 否 | "X-" | 身份 HTTP 头的前缀。`wolf-rbac` 在鉴权成功后,会在请求头 (用于传给后端) 及响应头 (用于传给前端) 中添加 3 个 header:`{prefix}UserId`、`{prefix}Username`、`{prefix}Nickname`。客户端传入的同名请求头会在鉴权前被移除。 |

## 接口

Expand Down Expand Up @@ -117,6 +125,10 @@ curl http://127.0.0.1:9180/apisix/admin/routes/1 \

你还可以通过 [APISIX Dashboard](https://github.com/apache/apisix-dashboard) 的 Web 界面完成上述操作。

## 升级

`header_prefix` 需要配置在 Route 或 Service 上,Consumer 不再支持该字段。升级前,请将 Consumer 上自定义的 `header_prefix` 移至每个使用 `wolf-rbac` 的 Route 或 Service(包括 `multi-auth` 中的 `wolf-rbac`),并从 Consumer 中删除。如果 Consumer 仍设置了默认值 `"X-"` 以外的值,校验将失败。`appid`、`server` 和 `ssl_verify` 仍配置在 Consumer 上。

<!--
![add a consumer](https://raw.githubusercontent.com/apache/apisix/master/docs/assets/images/plugin/wolf-rbac-1.png)

Expand Down
Loading
Loading