change(jwt-auth): when algorithm is not `RS256` or `ES256`, require the user to fill in `secret` (#12611)
diff --git a/apisix/plugins/jwt-auth.lua b/apisix/plugins/jwt-auth.lua
index b61d82d..5b838d9 100644
--- a/apisix/plugins/jwt-auth.lua
+++ b/apisix/plugins/jwt-auth.lua
@@ -17,11 +17,9 @@
local core = require("apisix.core")
local jwt = require("resty.jwt")
local consumer_mod = require("apisix.consumer")
-local resty_random = require("resty.random")
local new_tab = require ("table.new")
local auth_utils = require("apisix.utils.auth")
-local ngx_encode_base64 = ngx.encode_base64
local ngx_decode_base64 = ngx.decode_base64
local ngx = ngx
local sub_str = string.sub
@@ -144,8 +142,9 @@
return false, err
end
- if conf.algorithm ~= "RS256" and conf.algorithm ~= "ES256" and not conf.secret then
- conf.secret = ngx_encode_base64(resty_random.bytes(32, true))
+ if (conf.algorithm == "HS256" or conf.algorithm == "HS512") and not conf.secret then
+ return false, "property \"secret\" is required "..
+ "when \"algorithm\" is \"HS256\" or \"HS512\""
elseif conf.base64_secret then
if ngx_decode_base64(conf.secret) == nil then
return false, "base64_secret required but the secret is not in base64 format"
diff --git a/docs/en/latest/plugins/jwt-auth.md b/docs/en/latest/plugins/jwt-auth.md
index 36bac34..4434658 100644
--- a/docs/en/latest/plugins/jwt-auth.md
+++ b/docs/en/latest/plugins/jwt-auth.md
@@ -47,7 +47,7 @@
| Name | Type | Required | Default | Valid values | Description |
|---------------|---------|-------------------------------------------------------|---------|-----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| key | string | True | | non-empty | Unique key for a Consumer. |
-| secret | string | False | | non-empty | Shared key used to sign and verify the JWT when the algorithm is symmetric. Required when using `HS256` or `HS512` as the algorithm. If unspecified, the secret will be auto-generated. This field supports saving the value in Secret Manager using the [APISIX Secret](../terminology/secret.md) resource. |
+| secret | string | False | | non-empty | Shared key used to sign and verify the JWT when the algorithm is symmetric. Required when using `HS256` or `HS512` as the algorithm. This field supports saving the value in Secret Manager using the [APISIX Secret](../terminology/secret.md) resource. |
| public_key | string | True if `RS256` or `ES256` is set for the `algorithm` attribute. | | | RSA or ECDSA public key. This field supports saving the value in Secret Manager using the [APISIX Secret](../terminology/secret.md) resource. |
| algorithm | string | False | HS256 | ["HS256","HS512","RS256","ES256"] | Encryption algorithm. |
| exp | integer | False | 86400 | [1,...] | Expiry time of the token in seconds. |
diff --git a/docs/zh/latest/plugins/jwt-auth.md b/docs/zh/latest/plugins/jwt-auth.md
index de4ca1c..23d0b77 100644
--- a/docs/zh/latest/plugins/jwt-auth.md
+++ b/docs/zh/latest/plugins/jwt-auth.md
@@ -43,7 +43,7 @@
| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 |
| ------------- | ------- | ----- | ------- | --------------------------- | ------------------------------------------------------------------------------------------------------------ |
| key | string | 是 | | | 消费者的唯一密钥。 |
-| secret | string | 否 | | | 当使用对称算法时,用于对 JWT 进行签名和验证的共享密钥。使用 `HS256` 或 `HS512` 作为算法时必填。如果未指定,后台将会自动生成。该字段支持使用 [APISIX Secret](../terminology/secret.md) 资源,将值保存在 Secret Manager 中。 |
+| secret | string | 否 | | | 当使用对称算法时,用于对 JWT 进行签名和验证的共享密钥。使用 `HS256` 或 `HS512` 作为算法时必填。该字段支持使用 [APISIX Secret](../terminology/secret.md) 资源,将值保存在 Secret Manager 中。 |
| public_key | string | 否 | | | RSA 或 ECDSA 公钥, `algorithm` 属性选择 `RS256` 或 `ES256` 算法时必选。该字段支持使用 [APISIX Secret](../terminology/secret.md) 资源,将值保存在 Secret Manager 中。 |
| algorithm | string | 否 | "HS256" | ["HS256","HS512","RS256","ES256"] | 加密算法。 |
| exp | integer | 否 | 86400 | [1,...] | token 的超时时间。 |
diff --git a/t/plugin/jwt-auth.t b/t/plugin/jwt-auth.t
index 1c28123..0a71103 100644
--- a/t/plugin/jwt-auth.t
+++ b/t/plugin/jwt-auth.t
@@ -39,7 +39,7 @@
content_by_lua_block {
local plugin = require("apisix.plugins.jwt-auth")
local core = require("apisix.core")
- local conf = {key = "123"}
+ local conf = {key = "123", secret = "my-secret-key"}
local ok, err = plugin.check_schema(conf, core.schema.TYPE_CONSUMER)
if not ok then
@@ -50,7 +50,7 @@
}
}
--- response_body_like eval
-qr/{"algorithm":"HS256","base64_secret":false,"exp":86400,"key":"123","lifetime_grace_period":0,"secret":"[a-zA-Z0-9+\\\/]+={0,2}"}/
+qr/{"algorithm":"HS256","base64_secret":false,"exp":86400,"key":"123","lifetime_grace_period":0,"secret":"my-secret-key"}/
@@ -835,7 +835,7 @@
content_by_lua_block {
local plugin = require("apisix.plugins.jwt-auth")
local core = require("apisix.core")
- local conf = {key = "123", algorithm = "HS512"}
+ local conf = {key = "123", algorithm = "HS512", secret = "my-secret-key"}
local ok, err = plugin.check_schema(conf, core.schema.TYPE_CONSUMER)
if not ok then
@@ -846,7 +846,7 @@
}
}
--- response_body_like eval
-qr/{"algorithm":"HS512","base64_secret":false,"exp":86400,"key":"123","lifetime_grace_period":0,"secret":"[a-zA-Z0-9+\\\/]+={0,2}"}/
+qr/{"algorithm":"HS512","base64_secret":false,"exp":86400,"key":"123","lifetime_grace_period":0,"secret":"my-secret-key"}/
@@ -1222,3 +1222,49 @@
--- error_code: 400
--- response_body
{"error_msg":"invalid plugins configuration: failed to check the configuration of plugin jwt-auth err: failed to validate dependent schema for \"algorithm\": value should match only one schema, but matches none"}
+
+
+
+=== TEST 52: secret is required when algorithm is not RS256 or ES256
+--- config
+ location /t {
+ content_by_lua_block {
+ local core = require("apisix.core")
+ local plugin = require("apisix.plugins.jwt-auth")
+ -- default algorithm is HS256
+ local ok, err = plugin.check_schema({
+ key = "123",
+ }, core.schema.TYPE_CONSUMER)
+ assert(not ok, "secret should be required when algorithm is HS256(default)")
+
+ ok, err = plugin.check_schema({
+ key = "123",
+ algorithm = "HS256",
+ }, core.schema.TYPE_CONSUMER)
+ assert(not ok, "secret should be required when algorithm is HS256")
+
+ ok, err = plugin.check_schema({
+ key = "123",
+ algorithm = "HS512",
+ }, core.schema.TYPE_CONSUMER)
+ assert(not ok, "secret should be required when algorithm is HS512")
+
+ ok, err = plugin.check_schema({
+ key = "123",
+ algorithm = "RS256",
+ public_key = "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKebDxlvQMGyEesAL1r1nIJBkSdqu3Hr\n7noq/0ukiZqVQLSJPMOv0oxQSutvvK3hoibwGakDOza+xRITB7cs2cECAwEAAQ==\n-----END PUBLIC KEY-----"
+ }, core.schema.TYPE_CONSUMER)
+ assert(ok, "secret should not be required when algorithm is RS256")
+
+ ok, err = plugin.check_schema({
+ key = "123",
+ algorithm = "ES256",
+ public_key = "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKebDxlvQMGyEesAL1r1nIJBkSdqu3Hr\n7noq/0ukiZqVQLSJPMOv0oxQSutvvK3hoibwGakDOza+xRITB7cs2cECAwEAAQ==\n-----END PUBLIC KEY-----"
+ }, core.schema.TYPE_CONSUMER)
+ assert(ok, "secret should not be required when algorithm is ES256")
+
+ ngx.say("passed")
+ }
+ }
+--- response_body
+passed
diff --git a/t/plugin/public-api.t b/t/plugin/public-api.t
index 6b4c9f3..b961a3d 100644
--- a/t/plugin/public-api.t
+++ b/t/plugin/public-api.t
@@ -66,7 +66,8 @@
"plugins": {
"jwt-auth": {
"key": "user-key",
- "algorithm": "HS256"
+ "algorithm": "HS256",
+ "secret": "my-secret-key"
}
}
}]]