mirror of
https://gitee.com/iresty/apisix.git
synced 2024-11-30 11:07:59 +08:00
feature: Add wolf rbac plugin (#1095)
This commit is contained in:
parent
a9f05e531b
commit
5fff97d0b1
@ -87,7 +87,6 @@ grpc_server_example
|
||||
.travis.yml
|
||||
grpcurl
|
||||
t/servroot
|
||||
grpcurl
|
||||
|
||||
conf
|
||||
.travis/openwhisk-utilities
|
||||
|
@ -96,6 +96,7 @@ plugins: # plugin list
|
||||
- response-rewrite
|
||||
- fault-injection
|
||||
- udp-logger
|
||||
- wolf-rbac
|
||||
|
||||
stream_plugins:
|
||||
- mqtt-proxy
|
||||
|
BIN
doc/images/plugin/wolf-rbac-1.png
Normal file
BIN
doc/images/plugin/wolf-rbac-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
BIN
doc/images/plugin/wolf-rbac-2.png
Normal file
BIN
doc/images/plugin/wolf-rbac-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
207
doc/plugins/wolf-rbac-cn.md
Normal file
207
doc/plugins/wolf-rbac-cn.md
Normal file
@ -0,0 +1,207 @@
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
[English](wolf-rbac.md)
|
||||
|
||||
# 目录
|
||||
|
||||
- [**名字**](#名字)
|
||||
- [**属性**](#属性)
|
||||
- [**依赖项**](#依赖项)
|
||||
- [**如何启用**](#如何启用)
|
||||
- [**测试插件**](#测试插件)
|
||||
- [**禁用插件**](#禁用插件)
|
||||
|
||||
## 名字
|
||||
|
||||
`wolf-rbac` 是一个认证及授权(rbac)插件,它需要与 `consumer` 一起配合才能工作。同时需要添加 `wolf-rbac` 到一个 `service` 或 `route` 中。
|
||||
rbac功能由[wolf](https://github.com/iGeeky/wolf)提供, 有关 `wolf` 的更多信息, 请参考[wolf文档](https://github.com/iGeeky/wolf)。
|
||||
|
||||
|
||||
## 属性
|
||||
|
||||
* `server`: 设置 `wolf-server` 的访问地址, 如果未设置, 默认为: `http://127.0.0.1:10080`.
|
||||
* `appid`: 设置应用id, 该应用id, 需要是在 `wolf-console` 中已经添加的应用id.
|
||||
|
||||
|
||||
## 依赖项
|
||||
|
||||
### 安装 wolf, 并启动服务
|
||||
|
||||
[Wolf快速起步](https://github.com/iGeeky/wolf/blob/master/quick-start-with-docker/README-CN.md)
|
||||
|
||||
### 添加应用, 管理员, 普通用户, 权限, 资源 及给用户授权.
|
||||
|
||||
[Wolf管理使用](https://github.com/iGeeky/wolf/blob/master/docs/usage.md)
|
||||
|
||||
|
||||
## 如何启用
|
||||
|
||||
1. 创建一个 consumer 对象,并设置插件 `wolf-rbac` 的值。
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/consumers -X PUT -d '
|
||||
{
|
||||
"username":"wolf_rbac",
|
||||
"plugins":{
|
||||
"wolf-rbac":{
|
||||
"server":"http://127.0.0.1:10080",
|
||||
"appid":"restful"
|
||||
}
|
||||
},
|
||||
"desc":"wolf-rbac"
|
||||
}'
|
||||
```
|
||||
|
||||
你可以使用浏览器打开 dashboard:`http://127.0.0.1:9080/apisix/dashboard/`,通过 web 界面来完成上面的操作,先增加一个 consumer:
|
||||
![](../images/plugin/wolf-rbac-1.png)
|
||||
|
||||
然后在 consumer 页面中添加 wolf-rbac 插件:
|
||||
![](../images/plugin/wolf-rbac-2.png)
|
||||
|
||||
注意: 上面填写的 `appid` 需要在wolf控制台中已经存在的.
|
||||
|
||||
2. 创建 Route 或 Service 对象,并开启 `wolf-rbac` 插件。
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -X PUT -d '
|
||||
{
|
||||
"methods": ["GET"],
|
||||
"uri": "/*",
|
||||
"plugins": {
|
||||
"wolf-rbac": {}
|
||||
},
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"www.baidu.com:80": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## 测试插件
|
||||
|
||||
#### 首先进行登录获取 `wolf-rbac` token:
|
||||
|
||||
下面的 `appid`, `username`, `password` 必须为wolf系统中真实存在的.
|
||||
|
||||
* 以POST application/json方式登陆.
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/plugin/wolf-rbac/login -i \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"appid": "restful", "username":"test", "password":"user-password"}'
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Date: Wed, 24 Jul 2019 10:33:31 GMT
|
||||
Content-Type: text/plain
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Server: APISIX web server
|
||||
{"rbac_token":"V1#restful#eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NzQ5LCJ1c2VybmFtZSI6InRlc3QiLCJtYW5hZ2VyIjoiIiwiYXBwaWQiOiJyZXN0ZnVsIiwiaWF0IjoxNTc5NDQ5ODQxLCJleHAiOjE1ODAwNTQ2NDF9.n2-830zbhrEh6OAxn4K_yYtg5pqfmjpZAjoQXgtcuts","user_info":{"nickname":"test","username":"test","id":"749"}}
|
||||
```
|
||||
|
||||
* 以POST x-www-form-urlencoded方式登陆
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/plugin/wolf-rbac/login -i \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d 'appid=restful&username=test&password=user-password'
|
||||
```
|
||||
|
||||
|
||||
#### 使用获取到的 token 进行请求尝试
|
||||
|
||||
* 缺少 token
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/ -H"Host: www.baidu.com" -i
|
||||
|
||||
HTTP/1.1 401 Unauthorized
|
||||
...
|
||||
{"message":"Missing rbac token in request"}
|
||||
```
|
||||
|
||||
* token 放到请求头(Authorization)中:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/ -H"Host: www.baidu.com" \
|
||||
-H 'Authorization: V1#restful#eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NzQ5LCJ1c2VybmFtZSI6InRlc3QiLCJtYW5hZ2VyIjoiIiwiYXBwaWQiOiJyZXN0ZnVsIiwiaWF0IjoxNTc5NDQ5ODQxLCJleHAiOjE1ODAwNTQ2NDF9.n2-830zbhrEh6OAxn4K_yYtg5pqfmjpZAjoQXgtcuts' -i
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
<!DOCTYPE html>
|
||||
```
|
||||
|
||||
* token 放到请求头(x-rbac-token)中:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/ -H"Host: www.baidu.com" \
|
||||
-H 'x-rbac-token: V1#restful#eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NzQ5LCJ1c2VybmFtZSI6InRlc3QiLCJtYW5hZ2VyIjoiIiwiYXBwaWQiOiJyZXN0ZnVsIiwiaWF0IjoxNTc5NDQ5ODQxLCJleHAiOjE1ODAwNTQ2NDF9.n2-830zbhrEh6OAxn4K_yYtg5pqfmjpZAjoQXgtcuts' -i
|
||||
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
<!DOCTYPE html>
|
||||
```
|
||||
|
||||
* token 放到请求参数中:
|
||||
|
||||
```shell
|
||||
curl 'http://127.0.0.1:9080?rbac_token=V1%23restful%23eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NzQ5LCJ1c2VybmFtZSI6InRlc3QiLCJtYW5hZ2VyIjoiIiwiYXBwaWQiOiJyZXN0ZnVsIiwiaWF0IjoxNTc5NDQ5ODQxLCJleHAiOjE1ODAwNTQ2NDF9.n2-830zbhrEh6OAxn4K_yYtg5pqfmjpZAjoQXgtcuts' -H"Host: www.baidu.com" -i
|
||||
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
<!DOCTYPE html>
|
||||
```
|
||||
|
||||
* token 放到 cookie 中:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080 -H"Host: www.baidu.com" \
|
||||
--cookie x-rbac-token=V1#restful#eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NzQ5LCJ1c2VybmFtZSI6InRlc3QiLCJtYW5hZ2VyIjoiIiwiYXBwaWQiOiJyZXN0ZnVsIiwiaWF0IjoxNTc5NDQ5ODQxLCJleHAiOjE1ODAwNTQ2NDF9.n2-830zbhrEh6OAxn4K_yYtg5pqfmjpZAjoQXgtcuts -i
|
||||
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
<!DOCTYPE html>
|
||||
```
|
||||
|
||||
## 禁用插件
|
||||
|
||||
当你想去掉 `rbac-wolf` 插件的时候,很简单,在routes中的插件配置中把对应的 `插件` 配置删除即可,无须重启服务,即刻生效:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -X PUT -d '
|
||||
{
|
||||
"methods": ["GET"],
|
||||
"uri": "/*",
|
||||
"plugins": {
|
||||
},
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"www.baidu.com:80": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
209
doc/plugins/wolf-rbac.md
Normal file
209
doc/plugins/wolf-rbac.md
Normal file
@ -0,0 +1,209 @@
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
-->
|
||||
|
||||
[中文](wolf-rbac-cn.md)
|
||||
|
||||
# Summary
|
||||
|
||||
- [**Name**](#name)
|
||||
- [**Attributes**](#attributes)
|
||||
- [**Dependencies**](#dependencies)
|
||||
- [**How To Enable**](#how-to-enable)
|
||||
- [**Test Plugin**](#test-plugin)
|
||||
- [**Disable Plugin**](#disable-plugin)
|
||||
|
||||
## Name
|
||||
|
||||
`wolf-rbac` is an authentication and authorization (rbac) plugin. It needs to work with `consumer`. Also need to add `wolf-rbac` to a` service` or `route`.
|
||||
The rbac feature is provided by [wolf] (https://github.com/iGeeky/wolf). For more information about `wolf`, please refer to [wolf documentation] (https://github.com/iGeeky/wolf).
|
||||
|
||||
|
||||
## Attributes
|
||||
|
||||
* `server`: Set the service address of` wolf-server`. If not set, the default is: `http://127.0.0.1:10080`.
|
||||
* `appid`: Set the app id. The app id must be added in wolf-console.
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Install wolf and start the service
|
||||
|
||||
[Wolf quick start](https://github.com/iGeeky/wolf/blob/master/quick-start-with-docker/README.md)
|
||||
|
||||
### Add `application`,` admin`, `normal user`,` permission`, `resource` and user authorize
|
||||
|
||||
[Wolf-console usage](https://github.com/iGeeky/wolf/blob/master/docs/usage.md)
|
||||
|
||||
|
||||
## How To Enable
|
||||
|
||||
1. set a consumer and config the value of the `wolf-rbac`。
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/consumers -X PUT -d '
|
||||
{
|
||||
"username":"wolf_rbac",
|
||||
"plugins":{
|
||||
"wolf-rbac":{
|
||||
"server":"http://127.0.0.1:10080",
|
||||
"appid":"restful"
|
||||
}
|
||||
},
|
||||
"desc":"wolf-rbac"
|
||||
}'
|
||||
```
|
||||
|
||||
You can visit the dashboard: `http://127.0.0.1:9080/apisix/dashboard/`, to complete the above operations through the web interface, first add a consumer:
|
||||
![](../images/plugin/wolf-rbac-1.png)
|
||||
|
||||
Then add the wolf-rbac plugin to the consumer page:
|
||||
![](../images/plugin/wolf-rbac-2.png)
|
||||
|
||||
Notes: The `appid` filled in above needs to already exist in the wolf system.
|
||||
|
||||
1. Add a `Route` or `Service` and enable the wolf-rbac plugin.
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -X PUT -d '
|
||||
{
|
||||
"methods": ["GET"],
|
||||
"uri": "/*",
|
||||
"plugins": {
|
||||
"wolf-rbac": {}
|
||||
},
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"www.baidu.com:80": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## Test Plugin
|
||||
|
||||
#### Login and get `wolf-rbac` token:
|
||||
|
||||
The following `appid`,` username`, and `password` must be real ones in the wolf system.
|
||||
|
||||
* Login as `POST application/json`
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/plugin/wolf-rbac/login -i \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"appid": "restful", "username":"test", "password":"user-password"}'
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Date: Wed, 24 Jul 2019 10:33:31 GMT
|
||||
Content-Type: text/plain
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Server: APISIX web server
|
||||
{"rbac_token":"V1#restful#eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NzQ5LCJ1c2VybmFtZSI6InRlc3QiLCJtYW5hZ2VyIjoiIiwiYXBwaWQiOiJyZXN0ZnVsIiwiaWF0IjoxNTc5NDQ5ODQxLCJleHAiOjE1ODAwNTQ2NDF9.n2-830zbhrEh6OAxn4K_yYtg5pqfmjpZAjoQXgtcuts","user_info":{"nickname":"test","username":"test","id":"749"}}
|
||||
```
|
||||
|
||||
* Login as `POST x-www-form-urlencoded`
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/plugin/wolf-rbac/login -i \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d 'appid=restful&username=test&password=user-password'
|
||||
```
|
||||
|
||||
|
||||
#### try request with token
|
||||
|
||||
* without token
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/ -H"Host: www.baidu.com" -i
|
||||
|
||||
HTTP/1.1 401 Unauthorized
|
||||
...
|
||||
{"message":"Missing rbac token in request"}
|
||||
```
|
||||
|
||||
* request header(Authorization) with token:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/ -H"Host: www.baidu.com" \
|
||||
-H 'Authorization: V1#restful#eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NzQ5LCJ1c2VybmFtZSI6InRlc3QiLCJtYW5hZ2VyIjoiIiwiYXBwaWQiOiJyZXN0ZnVsIiwiaWF0IjoxNTc5NDQ5ODQxLCJleHAiOjE1ODAwNTQ2NDF9.n2-830zbhrEh6OAxn4K_yYtg5pqfmjpZAjoQXgtcuts' -i
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
<!DOCTYPE html>
|
||||
```
|
||||
|
||||
* request header(x-rbac-token) with token:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/ -H"Host: www.baidu.com" \
|
||||
-H 'x-rbac-token: V1#restful#eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NzQ5LCJ1c2VybmFtZSI6InRlc3QiLCJtYW5hZ2VyIjoiIiwiYXBwaWQiOiJyZXN0ZnVsIiwiaWF0IjoxNTc5NDQ5ODQxLCJleHAiOjE1ODAwNTQ2NDF9.n2-830zbhrEh6OAxn4K_yYtg5pqfmjpZAjoQXgtcuts' -i
|
||||
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
<!DOCTYPE html>
|
||||
```
|
||||
|
||||
* request params with token:
|
||||
|
||||
```shell
|
||||
curl 'http://127.0.0.1:9080?rbac_token=V1%23restful%23eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NzQ5LCJ1c2VybmFtZSI6InRlc3QiLCJtYW5hZ2VyIjoiIiwiYXBwaWQiOiJyZXN0ZnVsIiwiaWF0IjoxNTc5NDQ5ODQxLCJleHAiOjE1ODAwNTQ2NDF9.n2-830zbhrEh6OAxn4K_yYtg5pqfmjpZAjoQXgtcuts' -H"Host: www.baidu.com" -i
|
||||
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
<!DOCTYPE html>
|
||||
```
|
||||
|
||||
* request cookie with token:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080 -H"Host: www.baidu.com" \
|
||||
--cookie x-rbac-token=V1#restful#eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NzQ5LCJ1c2VybmFtZSI6InRlc3QiLCJtYW5hZ2VyIjoiIiwiYXBwaWQiOiJyZXN0ZnVsIiwiaWF0IjoxNTc5NDQ5ODQxLCJleHAiOjE1ODAwNTQ2NDF9.n2-830zbhrEh6OAxn4K_yYtg5pqfmjpZAjoQXgtcuts -i
|
||||
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
<!DOCTYPE html>
|
||||
```
|
||||
|
||||
## Disable Plugin
|
||||
|
||||
When you want to disable the `wolf-rbac` plugin, it is very simple,
|
||||
you can delete the corresponding json configuration in the plugin configuration,
|
||||
no need to restart the service, it will take effect immediately:
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -X PUT -d '
|
||||
{
|
||||
"methods": ["GET"],
|
||||
"uri": "/*",
|
||||
"plugins": {
|
||||
},
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"www.baidu.com:80": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
386
lua/apisix/plugins/wolf-rbac.lua
Normal file
386
lua/apisix/plugins/wolf-rbac.lua
Normal file
@ -0,0 +1,386 @@
|
||||
--
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
-- contributor license agreements. See the NOTICE file distributed with
|
||||
-- this work for additional information regarding copyright ownership.
|
||||
-- The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
-- (the "License"); you may not use this file except in compliance with
|
||||
-- the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
--
|
||||
|
||||
local core = require("apisix.core")
|
||||
local consumer = require("apisix.consumer")
|
||||
local json = require("apisix.core.json")
|
||||
local ngx_re = require("ngx.re")
|
||||
local http = require("resty.http")
|
||||
local ipairs = ipairs
|
||||
local ngx = ngx
|
||||
local tostring = tostring
|
||||
local rawget = rawget
|
||||
local rawset = rawset
|
||||
local setmetatable = setmetatable
|
||||
local type = type
|
||||
local string = string
|
||||
|
||||
local plugin_name = "wolf-rbac"
|
||||
|
||||
|
||||
local schema = {
|
||||
type = "object",
|
||||
properties = {
|
||||
appid = {
|
||||
type = "string",
|
||||
default = "unset"
|
||||
},
|
||||
server = {
|
||||
type = "string",
|
||||
default = "http://127.0.0.1:10080"
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
local _M = {
|
||||
version = 0.1,
|
||||
priority = 2555,
|
||||
type = 'auth',
|
||||
name = plugin_name,
|
||||
schema = schema,
|
||||
}
|
||||
|
||||
|
||||
local create_consume_cache
|
||||
do
|
||||
local consumer_ids = {}
|
||||
|
||||
function create_consume_cache(consumers)
|
||||
core.table.clear(consumer_ids)
|
||||
|
||||
for _, consumer in ipairs(consumers.nodes) do
|
||||
core.log.info("consumer node: ", core.json.delay_encode(consumer))
|
||||
consumer_ids[consumer.auth_conf.appid] = consumer
|
||||
end
|
||||
|
||||
return consumer_ids
|
||||
end
|
||||
|
||||
end -- do
|
||||
|
||||
local token_version = 'V1'
|
||||
local function create_rbac_token(appid, wolf_token)
|
||||
return token_version .. "#" .. appid .. "#" .. wolf_token
|
||||
end
|
||||
|
||||
local function parse_rbac_token(rbac_token)
|
||||
local res, err = ngx_re.split(rbac_token, "#", nil, nil, 3)
|
||||
if not res then
|
||||
return nil, err
|
||||
end
|
||||
|
||||
if #res ~= 3 or res[1] ~= token_version then
|
||||
return nil, 'invalid rbac token: version'
|
||||
end
|
||||
local appid = res[2]
|
||||
local wolf_token = res[3]
|
||||
|
||||
return {appid = appid, wolf_token = wolf_token}
|
||||
end
|
||||
|
||||
local function new_headers()
|
||||
local t = {}
|
||||
local lt = {}
|
||||
local _mt = {
|
||||
__index = function(t, k)
|
||||
return rawget(lt, string.lower(k))
|
||||
end,
|
||||
__newindex = function(t, k, v)
|
||||
rawset(t, k, v)
|
||||
rawset(lt, string.lower(k), v)
|
||||
end,
|
||||
}
|
||||
return setmetatable(t, _mt)
|
||||
end
|
||||
|
||||
-- timeout in ms
|
||||
local function http_req(method, uri, body, myheaders, timeout)
|
||||
if myheaders == nil then myheaders = new_headers() end
|
||||
|
||||
local httpc = http.new()
|
||||
if timeout then
|
||||
httpc:set_timeout(timeout)
|
||||
end
|
||||
|
||||
local params = {method = method, headers = myheaders, body = body, ssl_verify = false}
|
||||
local res, err = httpc:request_uri(uri, params)
|
||||
if err then
|
||||
core.log.error("FAIL REQUEST [ ",core.json.delay_encode(
|
||||
{method = method, uri = uri, body = body, headers = myheaders}),
|
||||
" ] failed! res is nil, err:", err)
|
||||
return nil, err
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
local function http_get(uri, myheaders, timeout)
|
||||
return http_req("GET", uri, nil, myheaders, timeout)
|
||||
end
|
||||
|
||||
local function http_post(uri, body, myheaders, timeout)
|
||||
return http_req("POST", uri, body, myheaders, timeout)
|
||||
end
|
||||
|
||||
function _M.check_schema(conf)
|
||||
core.log.info("input conf: ", core.json.delay_encode(conf))
|
||||
|
||||
local ok, err = core.schema.check(schema, conf)
|
||||
if not ok then
|
||||
return false, err
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
local function fetch_rbac_token(ctx)
|
||||
if ctx.var.arg_rbac_token then
|
||||
return ngx.unescape_uri(ctx.var.arg_rbac_token)
|
||||
end
|
||||
|
||||
if ctx.var.http_authorization then
|
||||
return ctx.var.http_authorization
|
||||
end
|
||||
|
||||
if ctx.var.http_x_rbac_token then
|
||||
return ctx.var.http_x_rbac_token
|
||||
end
|
||||
|
||||
return ctx.var['cookie_x-rbac-token']
|
||||
end
|
||||
|
||||
|
||||
local function check_url_permission(server, appid, action, resName, clientIP, wolf_token)
|
||||
local retry_max = 3
|
||||
local errmsg
|
||||
local userInfo
|
||||
local res
|
||||
local err
|
||||
local access_check_url = server .. "/wolf/rbac/access_check"
|
||||
local headers = new_headers()
|
||||
headers["x-rbac-token"] = wolf_token
|
||||
headers["Content-Type"] = "application/json; charset=utf-8"
|
||||
local args = { appID = appid, resName = resName, action = action, clientIP = clientIP}
|
||||
local url = access_check_url .. "?" .. ngx.encode_args(args)
|
||||
local timeout = 1000 * 10
|
||||
|
||||
for i = 1, retry_max do
|
||||
-- TODO: read apisix info.
|
||||
res, err = http_get(url, headers, timeout)
|
||||
if err then
|
||||
break
|
||||
else
|
||||
core.log.info("check permission request:", url, ", status:", res.status,
|
||||
",body:", core.json.delay_encode(res.body))
|
||||
if res.status < 500 then
|
||||
break
|
||||
else
|
||||
core.log.info("request [curl -v ", url, "] failed! status:", res.status)
|
||||
if i < retry_max then
|
||||
ngx.sleep(0.1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if err then
|
||||
core.log.error("fail request: ", url, ", err:", err)
|
||||
return {status = 500, err = "request to wolf-server failed, err:" .. tostring(err)}
|
||||
end
|
||||
|
||||
if res.status ~= 200 and res.status ~= 401 then
|
||||
return {status = 500, err = 'request to wolf-server failed, status:' .. tostring(res.status)}
|
||||
end
|
||||
|
||||
local body, err = json.decode(res.body)
|
||||
if err then
|
||||
errmsg = 'check permission failed! parse response json failed!'
|
||||
core.log.error( "json.decode(", res.body, ") failed! err:", err)
|
||||
return {status = res.status, err = errmsg}
|
||||
else
|
||||
if body.data then
|
||||
userInfo = body.data.userInfo
|
||||
end
|
||||
errmsg = body.reason
|
||||
return {status = res.status, err = errmsg, userInfo = userInfo}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function _M.rewrite(conf, ctx)
|
||||
local url = ctx.var.uri
|
||||
local action = ctx.var.request_method
|
||||
local clientIP = core.request.get_ip(ctx)
|
||||
local permItem = {action = action, url = url, clientIP = clientIP}
|
||||
core.log.info("hit wolf-rbac rewrite")
|
||||
|
||||
local rbac_token = fetch_rbac_token(ctx)
|
||||
if rbac_token == nil then
|
||||
core.log.info("no permission to access ", core.json.delay_encode(permItem), ", need login!")
|
||||
return 401, {message = "Missing rbac token in request"}
|
||||
end
|
||||
|
||||
local tokenInfo, err = parse_rbac_token(rbac_token)
|
||||
core.log.info("token info: ", core.json.delay_encode(tokenInfo), ", err: ", err)
|
||||
if err then
|
||||
return 401, {message = 'invalid rbac token: parse failed'}
|
||||
end
|
||||
|
||||
local appid = tokenInfo.appid
|
||||
local wolf_token = tokenInfo.wolf_token
|
||||
permItem.appid = appid
|
||||
permItem.wolf_token = wolf_token
|
||||
|
||||
local consumer_conf = consumer.plugin(plugin_name)
|
||||
if not consumer_conf then
|
||||
return 401, {message = "Missing related consumer"}
|
||||
end
|
||||
|
||||
local consumers = core.lrucache.plugin(plugin_name, "consumers_key",
|
||||
consumer_conf.conf_version,
|
||||
create_consume_cache, consumer_conf)
|
||||
|
||||
core.log.info("------ consumers: ", core.json.delay_encode(consumers))
|
||||
local consumer = consumers[appid]
|
||||
if not consumer then
|
||||
core.log.error("consumer [", appid, "] not found")
|
||||
return 401, {message = "Invalid appid in rbac token"}
|
||||
end
|
||||
core.log.info("consumer: ", core.json.delay_encode(consumer))
|
||||
local server = consumer.auth_conf.server
|
||||
|
||||
local url = ctx.var.uri
|
||||
local action = ctx.var.request_method
|
||||
local clientIP = core.request.get_ip(ctx)
|
||||
local permItem = {appid = appid, action = action, url = url, clientIP = clientIP, wolf_token = wolf_token}
|
||||
|
||||
local res = check_url_permission(server, appid, action, url, clientIP, wolf_token)
|
||||
core.log.info(" check_url_permission(", core.json.delay_encode(permItem), ") res: ",core.json.delay_encode(res))
|
||||
|
||||
local username = nil
|
||||
local nickname = nil
|
||||
if type(res.userInfo) == 'table' then
|
||||
local userInfo = res.userInfo
|
||||
core.response.set_header("X-UserId", userInfo.id)
|
||||
core.response.set_header("X-Username", userInfo.username)
|
||||
core.response.set_header("X-Nickname", ngx.escape_uri(userInfo.nickname) or userInfo.username)
|
||||
ctx.userInfo = userInfo
|
||||
username = userInfo.username
|
||||
nickname = userInfo.nickname
|
||||
end
|
||||
|
||||
if res.status ~= 200 then
|
||||
-- no permission.
|
||||
core.log.error(" check_url_permission(", core.json.delay_encode(permItem),
|
||||
") failed, res: ",core.json.delay_encode(res))
|
||||
return 401, {message = res.err, username = username, nickname = nickname}
|
||||
end
|
||||
core.log.info("wolf-rbac check permission passed")
|
||||
end
|
||||
|
||||
local function get_args()
|
||||
local ctx = ngx.ctx.api_ctx
|
||||
local args, err
|
||||
ngx.req.read_body()
|
||||
if string.find(ctx.var.http_content_type or "","application/json", 1, true) then
|
||||
args, err = json.decode(ngx.req.get_body_data())
|
||||
if err then
|
||||
core.log.error("json.decode(", ngx.req.get_body_data(), ") failed! ", err)
|
||||
end
|
||||
else
|
||||
args = ngx.req.get_post_args()
|
||||
end
|
||||
return args
|
||||
end
|
||||
|
||||
local function login()
|
||||
local args = get_args()
|
||||
if not args then
|
||||
return core.response.exit(400, {message = "invalid request"})
|
||||
end
|
||||
if not args.appid then
|
||||
return core.response.exit(400, {message = "appid is missing"})
|
||||
end
|
||||
|
||||
local appid = args.appid
|
||||
|
||||
local consumer_conf = consumer.plugin(plugin_name)
|
||||
if not consumer_conf then
|
||||
return core.response.exit(500)
|
||||
end
|
||||
|
||||
local consumers = core.lrucache.plugin(plugin_name, "consumers_key",
|
||||
consumer_conf.conf_version,
|
||||
create_consume_cache, consumer_conf)
|
||||
|
||||
core.log.info("------ consumers: ", core.json.delay_encode(consumers))
|
||||
local consumer = consumers[appid]
|
||||
if not consumer then
|
||||
core.log.info("request appid [", appid, "] not found")
|
||||
return core.response.exit(400, {message = "appid [" .. tostring(appid) .. "] not found"})
|
||||
end
|
||||
|
||||
core.log.info("consumer: ", core.json.delay_encode(consumer))
|
||||
|
||||
local uri = consumer.auth_conf.server .. '/wolf/rbac/login.rest'
|
||||
local headers = new_headers()
|
||||
headers["Content-Type"] = "application/json; charset=utf-8"
|
||||
local timeout = 1000 * 5
|
||||
local request_debug = core.json.delay_encode(
|
||||
{method = 'POST', uri = uri, body = args, headers = headers,timeout = timeout})
|
||||
core.log.info("login request [", request_debug, "] ....")
|
||||
local res, err = http_post(uri, core.json.encode(args), headers, timeout)
|
||||
if err or not res then
|
||||
core.log.error("login request [", request_debug, "] failed! err: ", err)
|
||||
return core.response.exit(500, {message = "request to wolf-server failed! " .. tostring(err)})
|
||||
end
|
||||
core.log.info("login request [", request_debug, "] status: ", res.status, ", body: ", res.body)
|
||||
|
||||
if res.status ~= 200 then
|
||||
core.log.error("login request [", request_debug, "] failed! status: ", res.status)
|
||||
return core.response.exit(500, {message = "request to wolf-server failed! status:" .. tostring(res.status) })
|
||||
end
|
||||
local body, err = json.decode(res.body)
|
||||
if err or not body then
|
||||
core.log.error("login request [", request_debug, "] failed! err:", err)
|
||||
return core.response.exit(500, {message = "request to wolf-server failed!"})
|
||||
end
|
||||
if not body.ok then
|
||||
core.log.error("user login [", request_debug, "] failed! response body:", core.json.delay_encode(body))
|
||||
return core.response.exit(200, {message = body.reason})
|
||||
end
|
||||
core.log.info("user login [", request_debug, "] success! response body:", core.json.delay_encode(body))
|
||||
|
||||
local userInfo = body.data.userInfo
|
||||
local wolf_token = body.data.token
|
||||
|
||||
local rbac_token = create_rbac_token(appid, wolf_token)
|
||||
core.response.exit(200, {rbac_token = rbac_token, user_info = userInfo})
|
||||
end
|
||||
|
||||
function _M.api()
|
||||
return {
|
||||
{
|
||||
methods = {"POST"},
|
||||
uri = "/apisix/plugin/wolf-rbac/login",
|
||||
handler = login,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
return _M
|
@ -30,6 +30,6 @@ __DATA__
|
||||
--- request
|
||||
GET /apisix/admin/plugins/list
|
||||
--- response_body_like eval
|
||||
qr/\["limit-req","limit-count","limit-conn","key-auth","basic-auth","prometheus","node-status","jwt-auth","zipkin","ip-restriction","grpc-transcode","serverless-pre-function","serverless-post-function","openid-connect","proxy-rewrite","redirect","response-rewrite","fault-injection",["udp-logger"]\]/
|
||||
qr/\["limit-req","limit-count","limit-conn","key-auth","basic-auth","prometheus","node-status","jwt-auth","zipkin","ip-restriction","grpc-transcode","serverless-pre-function","serverless-post-function","openid-connect","proxy-rewrite","redirect","response-rewrite","fault-injection","udp-logger","wolf-rbac"\]/
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
@ -59,6 +59,7 @@ loaded plugin and sort by priority: 11000 name: fault-injection
|
||||
loaded plugin and sort by priority: 10000 name: serverless-pre-function
|
||||
loaded plugin and sort by priority: 3000 name: ip-restriction
|
||||
loaded plugin and sort by priority: 2599 name: openid-connect
|
||||
loaded plugin and sort by priority: 2555 name: wolf-rbac
|
||||
loaded plugin and sort by priority: 2520 name: basic-auth
|
||||
loaded plugin and sort by priority: 2510 name: jwt-auth
|
||||
loaded plugin and sort by priority: 2500 name: key-auth
|
||||
|
@ -15,6 +15,7 @@
|
||||
-- limitations under the License.
|
||||
--
|
||||
local json_decode = require("cjson").decode
|
||||
local json_encode = require("cjson").encode
|
||||
|
||||
local _M = {}
|
||||
|
||||
@ -31,6 +32,9 @@ end
|
||||
function _M.server_port()
|
||||
ngx.print(ngx.var.server_port)
|
||||
end
|
||||
_M.server_port_route2 = _M.server_port
|
||||
_M.server_port_hello = _M.server_port
|
||||
_M.server_port_aa = _M.server_port
|
||||
|
||||
|
||||
function _M.limit_conn()
|
||||
@ -69,6 +73,8 @@ function _M.uri()
|
||||
ngx.say(k, ": ", v)
|
||||
end
|
||||
end
|
||||
_M.uri_plugin_proxy_rewrite = _M.uri
|
||||
_M.uri_plugin_proxy_rewrite_args = _M.uri
|
||||
|
||||
function _M.old_uri()
|
||||
-- ngx.sleep(1)
|
||||
@ -112,6 +118,50 @@ function _M.mock_zipkin()
|
||||
end
|
||||
end
|
||||
|
||||
function _M.wolf_rbac_login_rest()
|
||||
ngx.req.read_body()
|
||||
local data = ngx.req.get_body_data()
|
||||
local args = json_decode(data)
|
||||
if not args.username then
|
||||
ngx.say(json_encode({ok=false, reason="ERR_USERNAME_MISSING"}))
|
||||
ngx.exit(0)
|
||||
end
|
||||
if not args.password then
|
||||
ngx.say(json_encode({ok=false, reason="ERR_PASSWORD_MISSING"}))
|
||||
ngx.exit(0)
|
||||
end
|
||||
if args.username ~= "admin" then
|
||||
ngx.say(json_encode({ok=false, reason="ERR_USER_NOT_FOUND"}))
|
||||
ngx.exit(0)
|
||||
end
|
||||
if args.password ~= "123456" then
|
||||
ngx.say(json_encode({ok=false, reason="ERR_PASSWORD_ERROR"}))
|
||||
ngx.exit(0)
|
||||
end
|
||||
|
||||
ngx.say(json_encode({ok=true, data={token="wolf-rbac-token",
|
||||
userInfo={nickname="administrator",username="admin", id="100"}}}))
|
||||
end
|
||||
|
||||
function _M.wolf_rbac_access_check()
|
||||
local headers = ngx.req.get_headers()
|
||||
local token = headers['x-rbac-token']
|
||||
if token ~= 'wolf-rbac-token' then
|
||||
ngx.say(json_encode({ok=false, reason="ERR_TOKEN_INVALID"}))
|
||||
ngx.exit(0)
|
||||
end
|
||||
|
||||
local args = ngx.req.get_uri_args()
|
||||
local resName = args.resName
|
||||
if resName == '/hello' then
|
||||
ngx.say(json_encode({ok=true, data={ userInfo={nickname="administrator",username="admin", id="100"} }}))
|
||||
else
|
||||
ngx.status = 401
|
||||
ngx.say(json_encode({ok=false, reason="no permission to access"}))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function _M.websocket_handshake()
|
||||
local websocket = require "resty.websocket.server"
|
||||
local wb, err = websocket:new()
|
||||
@ -120,15 +170,11 @@ function _M.websocket_handshake()
|
||||
return ngx.exit(400)
|
||||
end
|
||||
end
|
||||
|
||||
_M.websocket_handshake_route = _M.websocket_handshake
|
||||
|
||||
function _M.go()
|
||||
local action = string.sub(ngx.var.uri, 2)
|
||||
local find = string.find(action, "/", 1, true)
|
||||
if find then
|
||||
action = string.sub(action, 1, find - 1)
|
||||
end
|
||||
|
||||
action = string.gsub(action, "[/\\.]", "_")
|
||||
if not action or not _M[action] then
|
||||
return ngx.exit(404)
|
||||
end
|
||||
|
334
t/plugin/wolf-rbac.t
Normal file
334
t/plugin/wolf-rbac.t
Normal file
@ -0,0 +1,334 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
use t::APISIX 'no_plan';
|
||||
|
||||
|
||||
repeat_each(1);
|
||||
no_long_string();
|
||||
no_root_location();
|
||||
no_shuffle();
|
||||
run_tests;
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: sanity
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local plugin = require("apisix.plugins.wolf-rbac")
|
||||
local conf = {
|
||||
|
||||
}
|
||||
|
||||
local ok, err = plugin.check_schema(conf)
|
||||
if not ok then
|
||||
ngx.say(err)
|
||||
end
|
||||
|
||||
ngx.say(require("cjson").encode(conf))
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body_like eval
|
||||
qr/{"appid":"unset","server":"http:\\\/\\\/127\.0\.0\.1:10080"}/
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
=== TEST 2: wrong type of string
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local plugin = require("apisix.plugins.wolf-rbac")
|
||||
local ok, err = plugin.check_schema({appid = 123})
|
||||
if not ok then
|
||||
ngx.say(err)
|
||||
end
|
||||
|
||||
ngx.say("done")
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
property "appid" validation failed: wrong type: expected string, got number
|
||||
done
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
=== TEST 3: add consumer with username and plugins
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local t = require("lib.test_admin").test
|
||||
local code, body = t('/apisix/admin/consumers',
|
||||
ngx.HTTP_PUT,
|
||||
[[{
|
||||
"username": "wolf_rbac_unit_test",
|
||||
"plugins": {
|
||||
"wolf-rbac": {
|
||||
"appid": "wolf-rbac-app",
|
||||
"server": "http://127.0.0.1:1982"
|
||||
}
|
||||
}
|
||||
}]],
|
||||
[[{
|
||||
"node": {
|
||||
"value": {
|
||||
"username": "wolf_rbac_unit_test",
|
||||
"plugins": {
|
||||
"wolf-rbac": {
|
||||
"appid": "wolf-rbac-app",
|
||||
"server": "http://127.0.0.1:1982"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"action": "set"
|
||||
}]]
|
||||
)
|
||||
|
||||
ngx.status = code
|
||||
ngx.say(body)
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
passed
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
=== TEST 4: enable wolf rbac plugin using admin api
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
local t = require("lib.test_admin").test
|
||||
local code, body = t('/apisix/admin/routes/1',
|
||||
ngx.HTTP_PUT,
|
||||
[[{
|
||||
"plugins": {
|
||||
"wolf-rbac": {}
|
||||
},
|
||||
"upstream": {
|
||||
"nodes": {
|
||||
"127.0.0.1:1982": 1
|
||||
},
|
||||
"type": "roundrobin"
|
||||
},
|
||||
"uri": "/hello*"
|
||||
}]]
|
||||
)
|
||||
|
||||
if code >= 300 then
|
||||
ngx.status = code
|
||||
end
|
||||
ngx.say(body)
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
passed
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
=== TEST 5: login failed, appid is missing
|
||||
--- request
|
||||
POST /apisix/plugin/wolf-rbac/login
|
||||
username=admin&password=123456
|
||||
--- more_headers
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
--- error_code: 400
|
||||
--- response_body_like eval
|
||||
qr/appid is missing/
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
=== TEST 6: login failed, appid not found
|
||||
--- request
|
||||
POST /apisix/plugin/wolf-rbac/login
|
||||
appid=not-found&username=admin&password=123456
|
||||
--- more_headers
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
--- error_code: 400
|
||||
--- response_body_like eval
|
||||
qr/appid \[not-found\] not found/
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
=== TEST 7: login failed, username missing
|
||||
--- request
|
||||
POST /apisix/plugin/wolf-rbac/login
|
||||
appid=wolf-rbac-app&password=123456
|
||||
--- more_headers
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
--- error_code: 200
|
||||
--- response_body_like eval
|
||||
qr/ERR_USERNAME_MISSING/
|
||||
|
||||
|
||||
=== TEST 8: login failed, password missing
|
||||
--- request
|
||||
POST /apisix/plugin/wolf-rbac/login
|
||||
appid=wolf-rbac-app&username=admin
|
||||
--- more_headers
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
--- error_code: 200
|
||||
--- response_body_like eval
|
||||
qr/ERR_PASSWORD_MISSING/
|
||||
|
||||
|
||||
=== TEST 9: login failed, username not found
|
||||
--- request
|
||||
POST /apisix/plugin/wolf-rbac/login
|
||||
appid=wolf-rbac-app&username=not-found&password=123456
|
||||
--- more_headers
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
--- error_code: 200
|
||||
--- response_body_like eval
|
||||
qr/ERR_USER_NOT_FOUND/
|
||||
|
||||
|
||||
=== TEST 10: login failed, wrong password
|
||||
--- request
|
||||
POST /apisix/plugin/wolf-rbac/login
|
||||
appid=wolf-rbac-app&username=admin&password=wrong-password
|
||||
--- more_headers
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
--- error_code: 200
|
||||
--- response_body_like eval
|
||||
qr/ERR_PASSWORD_ERROR/
|
||||
|
||||
|
||||
=== TEST 11: login successfully
|
||||
--- request
|
||||
POST /apisix/plugin/wolf-rbac/login
|
||||
{"appid": "wolf-rbac-app", "username": "admin","password": "123456"}
|
||||
--- more_headers
|
||||
Content-Type: application/json
|
||||
--- error_code: 200
|
||||
--- response_body_like eval
|
||||
qr/{"rbac_token":"V1#wolf-rbac-app#wolf-rbac-token","user_info":{"nickname":"administrator","username":"admin","id":"100"}}/
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
|
||||
=== TEST 21: verify, missing token
|
||||
--- request
|
||||
GET /hello
|
||||
--- error_code: 401
|
||||
--- response_body
|
||||
{"message":"Missing rbac token in request"}
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
=== TEST 22: verify: invalid rbac token
|
||||
--- request
|
||||
GET /hello
|
||||
--- error_code: 401
|
||||
--- more_headers
|
||||
x-rbac-token: invalid-rbac-token
|
||||
--- response_body
|
||||
{"message":"invalid rbac token: parse failed"}
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
=== TEST 23: verify: invalid appid in rbac token
|
||||
--- request
|
||||
GET /hello
|
||||
--- error_code: 401
|
||||
--- more_headers
|
||||
x-rbac-token: V1#invalid-appid#rbac-token
|
||||
--- response_body
|
||||
{"message":"Invalid appid in rbac token"}
|
||||
|
||||
|
||||
=== TEST 24: verify: failed
|
||||
--- request
|
||||
GET /hello1
|
||||
--- error_code: 401
|
||||
--- more_headers
|
||||
x-rbac-token: V1#wolf-rbac-app#wolf-rbac-token
|
||||
--- response_body
|
||||
{"message":"no permission to access"}
|
||||
|
||||
|
||||
=== TEST 25: verify (in argument)
|
||||
--- request
|
||||
GET /hello?rbac_token=V1%23wolf-rbac-app%23wolf-rbac-token
|
||||
--- response_headers
|
||||
X-UserId: 100
|
||||
X-Username: admin
|
||||
X-Nickname: administrator
|
||||
--- response_body
|
||||
hello world
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
=== TEST 26: verify (in header Authorization)
|
||||
--- request
|
||||
GET /hello
|
||||
--- more_headers
|
||||
Authorization: V1#wolf-rbac-app#wolf-rbac-token
|
||||
--- response_headers
|
||||
X-UserId: 100
|
||||
X-Username: admin
|
||||
X-Nickname: administrator
|
||||
--- response_body
|
||||
hello world
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
=== TEST 27: verify (in header x-rbac-token)
|
||||
--- request
|
||||
GET /hello
|
||||
--- more_headers
|
||||
x-rbac-token: V1#wolf-rbac-app#wolf-rbac-token
|
||||
--- response_headers
|
||||
X-UserId: 100
|
||||
X-Username: admin
|
||||
X-Nickname: administrator
|
||||
--- response_body
|
||||
hello world
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
=== TEST 28: verify (in cookie)
|
||||
--- request
|
||||
GET /hello
|
||||
--- more_headers
|
||||
Cookie: x-rbac-token=V1#wolf-rbac-app#wolf-rbac-token
|
||||
--- response_headers
|
||||
X-UserId: 100
|
||||
X-Username: admin
|
||||
X-Nickname: administrator
|
||||
--- response_body
|
||||
hello world
|
||||
--- no_error_log
|
||||
[error]
|
Loading…
Reference in New Issue
Block a user