You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2022/03/14 03:43:45 UTC
[apisix] branch master updated: feat: jwt-plugin support custom parameters (#6561)
This is an automated email from the ASF dual-hosted git repository.
spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 6182ba9 feat: jwt-plugin support custom parameters (#6561)
6182ba9 is described below
commit 6182ba9f962c4352456b4b65cec3d69354737341
Author: Gaoll <lx...@126.com>
AuthorDate: Mon Mar 14 11:43:35 2022 +0800
feat: jwt-plugin support custom parameters (#6561)
Co-authored-by: 高亮亮 <gl...@alibaba-inc.com>
---
apisix/plugins/jwt-auth.lua | 25 +++++--
docs/en/latest/plugins/jwt-auth.md | 10 +++
docs/zh/latest/plugins/jwt-auth.md | 10 +++
t/plugin/jwt-auth2.t | 149 +++++++++++++++++++++++++++++++++++++
4 files changed, 188 insertions(+), 6 deletions(-)
diff --git a/apisix/plugins/jwt-auth.lua b/apisix/plugins/jwt-auth.lua
index d1282cd..eea7159 100644
--- a/apisix/plugins/jwt-auth.lua
+++ b/apisix/plugins/jwt-auth.lua
@@ -36,7 +36,20 @@ local lrucache = core.lrucache.new({
local schema = {
type = "object",
- properties = {},
+ properties = {
+ header = {
+ type = "string",
+ default = "authorization"
+ },
+ query = {
+ type = "string",
+ default = "jwt"
+ },
+ cookie = {
+ type = "string",
+ default = "jwt"
+ }
+ },
}
local consumer_schema = {
@@ -171,8 +184,8 @@ function _M.check_schema(conf, schema_type)
end
-local function fetch_jwt_token(ctx)
- local token = core.request.header(ctx, "authorization")
+local function fetch_jwt_token(conf, ctx)
+ local token = core.request.header(ctx, conf.header)
if token then
local prefix = sub_str(token, 1, 7)
if prefix == 'Bearer ' or prefix == 'bearer ' then
@@ -182,12 +195,12 @@ local function fetch_jwt_token(ctx)
return token
end
- token = ctx.var.arg_jwt
+ token = ctx.var["arg_" .. conf.query]
if token then
return token
end
- local val = ctx.var.cookie_jwt
+ local val = ctx.var["cookie_" .. conf.cookie]
if not val then
return nil, "JWT not found in cookie"
end
@@ -339,7 +352,7 @@ end
function _M.rewrite(conf, ctx)
- local jwt_token, err = fetch_jwt_token(ctx)
+ local jwt_token, err = fetch_jwt_token(conf, ctx)
if not jwt_token then
core.log.info("failed to fetch JWT token: ", err)
return 401, {message = "Missing JWT token in request"}
diff --git a/docs/en/latest/plugins/jwt-auth.md b/docs/en/latest/plugins/jwt-auth.md
index a026ce8..5fe10f3 100644
--- a/docs/en/latest/plugins/jwt-auth.md
+++ b/docs/en/latest/plugins/jwt-auth.md
@@ -33,6 +33,8 @@ For more information on JWT, refer to [JWT](https://jwt.io/) for more informatio
## Attributes
+For consumer side:
+
| Name | Type | Requirement | Default | Valid | Description |
|:--------------|:--------|:------------|:--------|:----------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------|
| key | string | required | | | different `consumer` have different value, it's unique. different `consumer` use the same `key`, and there will be a request matching exception. |
@@ -46,6 +48,14 @@ For more information on JWT, refer to [JWT](https://jwt.io/) for more informatio
**Note**: To enable vault integration, first visit the [config.yaml](https://github.com/apache/apisix/blob/master/conf/config.yaml) update it with your vault server configuration, host address and access token. You can take a look of what APISIX expects from the config.yaml at [config-default.yaml](https://github.com/apache/apisix/blob/master/conf/config-default.yaml) under the vault attributes.
+For route side:
+
+| Name | Type | Requirement | Default | Valid | Description |
+| ---- | ------ | ----------- | ------- | ----- | ---------------------------------------------------------------------------- |
+| header | string | optional | authorization | | the header we get the token from |
+| query | string | optional | jwt | | the query string we get the token from, which priority is lower than header |
+| cookie | string | optional | jwt | | the cookie we get the token from, which priority is lower than querystring |
+
## API
This plugin will add `/apisix/plugin/jwt/sign` to sign.
diff --git a/docs/zh/latest/plugins/jwt-auth.md b/docs/zh/latest/plugins/jwt-auth.md
index 37782b5..55644f4 100644
--- a/docs/zh/latest/plugins/jwt-auth.md
+++ b/docs/zh/latest/plugins/jwt-auth.md
@@ -44,6 +44,8 @@ title: jwt-auth
## 属性
+consumer 端配置:
+
| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 |
| :------------ | :------ | :----- | :------ | :-------------------------- | :------------------------------------------------------------------------------------------------------------ |
| key | string | 必须 | | | 不同的 `consumer` 对象应有不同的值,它应当是唯一的。不同 consumer 使用了相同的 `key` ,将会出现请求匹配异常。 |
@@ -57,6 +59,14 @@ title: jwt-auth
**注意**: 要启用 Vault 集成,首先访问 [config.yaml](https://github.com/apache/apisix/blob/master/conf/config.yaml),更新您的 Vault 服务器配置、主机地址和访问令牌。您可以在 [config-default.yaml](https://github.com/apache/apisix/blob/master/conf/config-default.yaml) 中 vault 属性下查看 APISIX 的默认配置。
+router 端配置:
+
+| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 |
+| ---- | ------ | ------ | ------ | ------ | ------------------------------------------------------------------------------------------------------------- |
+| header | string | 可选| authorization | | 设置我们从哪个 header 获取 token。 |
+| query | string | 可选 | jwt | | 设置我们从哪个 query string 获取 token,优先级低于header |
+| cookie | string | 可选 | jwt | | 设置我们从哪个 cookie 获取 token,优先级低于query |
+
## 接口
插件会增加 `/apisix/plugin/jwt/sign` 这个接口,需要通过 [public-api](../../../en/latest/plugins/public-api.md) 插件来暴露它。
diff --git a/t/plugin/jwt-auth2.t b/t/plugin/jwt-auth2.t
new file mode 100644
index 0000000..a6c6f31
--- /dev/null
+++ b/t/plugin/jwt-auth2.t
@@ -0,0 +1,149 @@
+#
+# 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();
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+
+ if ((!defined $block->error_log) && (!defined $block->no_error_log)) {
+ $block->set_value("no_error_log", "[error]");
+ }
+
+ if (!defined $block->request) {
+ $block->set_value("request", "GET /t");
+ }
+});
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: 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": "jack",
+ "plugins": {
+ "jwt-auth": {
+ "key": "user-key",
+ "secret": "my-secret-key"
+ }
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 2: enable jwt auth plugin using admin api with custom parameter
+--- 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": {
+ "jwt-auth": {
+ "header": "jwt-header",
+ "query": "jwt-query",
+ "cookie": "jwt-cookie"
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 3: verify (in header)
+--- request
+GET /hello
+--- more_headers
+jwt-header: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
+--- response_body
+hello world
+
+
+
+=== TEST 4: verify (in cookie)
+--- request
+GET /hello
+--- more_headers
+Cookie: jwt-cookie=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
+--- response_body
+hello world
+
+
+
+=== TEST 5: verify (in query)
+--- request
+GET /hello?jwt-query=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
+--- response_body
+hello world
+
+
+
+=== TEST 6: verify (in header without Bearer)
+--- request
+GET /hello
+--- more_headers
+jwt-header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
+--- response_body
+hello world
+
+
+
+=== TEST 7: verify (in header with bearer)
+--- request
+GET /hello
+--- more_headers
+jwt-header: bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs
+--- response_body
+hello world