From 37f6f81a1a9c18895db1c61cca62785980fe9d10 Mon Sep 17 00:00:00 2001 From: soulbird Date: Fri, 6 Jan 2023 17:12:09 +0800 Subject: [PATCH] feat(secret): add ci and doc for some auth plugins (#8601) Co-authored-by: soulbird --- docs/en/latest/plugins/basic-auth.md | 2 +- docs/en/latest/plugins/hmac-auth.md | 2 +- docs/en/latest/plugins/jwt-auth.md | 6 +- docs/en/latest/plugins/key-auth.md | 2 +- docs/en/latest/plugins/ldap-auth.md | 2 +- docs/en/latest/plugins/wolf-rbac.md | 2 +- docs/zh/latest/plugins/basic-auth.md | 2 +- docs/zh/latest/plugins/hmac-auth.md | 2 +- docs/zh/latest/plugins/jwt-auth.md | 6 +- docs/zh/latest/plugins/key-auth.md | 2 +- docs/zh/latest/plugins/ldap-auth.md | 2 +- docs/zh/latest/plugins/wolf-rbac.md | 2 +- t/plugin/basic-auth.t | 88 ++++++++++++ t/plugin/hmac-auth4.t | 168 +++++++++++++++++++++++ t/plugin/jwt-auth3.t | 198 +++++++++++++++++++++++++++ t/plugin/key-auth.t | 39 ++---- t/plugin/ldap-auth.t | 91 ++++++++++++ t/plugin/wolf-rbac.t | 73 ++++++++++ 18 files changed, 645 insertions(+), 44 deletions(-) create mode 100644 t/plugin/hmac-auth4.t diff --git a/docs/en/latest/plugins/basic-auth.md b/docs/en/latest/plugins/basic-auth.md index 8447a4fce5d4..64f3714dbaae 100644 --- a/docs/en/latest/plugins/basic-auth.md +++ b/docs/en/latest/plugins/basic-auth.md @@ -40,7 +40,7 @@ For Consumer: | Name | Type | Required | Description | |----------|--------|----------|------------------------------------------------------------------------------------------------------------------------| | username | string | True | Unique username for a Consumer. If multiple Consumers use the same `username`, a request matching exception is raised. | -| password | string | True | Password of the user. | +| password | string | True | Password of the user. This field supports saving the value in Secret Manager using the [APISIX Secret](../terminology/secret.md) resource. | NOTE: `encrypt_fields = {"password"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields). diff --git a/docs/en/latest/plugins/hmac-auth.md b/docs/en/latest/plugins/hmac-auth.md index 5aaef2eb3247..5fa1489f3072 100644 --- a/docs/en/latest/plugins/hmac-auth.md +++ b/docs/en/latest/plugins/hmac-auth.md @@ -38,7 +38,7 @@ This Plugin works with a [Consumer](../terminology/consumer.md) object and a con | Name | Type | Required | Default | Valid values | Description | |-----------------------|---------------|----------|---------------|---------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | access_key | string | True | | | Unique key of a Consumer. If different Consumers have the same key, a request matching exception will occur. | -| secret_key | string | True | | | Used in pair with `access_key`. | +| secret_key | string | True | | | Used in pair with `access_key`. This field supports saving the value in Secret Manager using the [APISIX Secret](../terminology/secret.md) resource. | | algorithm | string | False | "hmac-sha256" | ["hmac-sha1", "hmac-sha256", "hmac-sha512"] | Encryption algorithm used. | | clock_skew | integer | False | 0 | | Clock skew allowed by the signature in seconds. Setting it to `0` will skip checking the date. | | signed_headers | array[string] | False | | | List of headers to be used in the encryption algorithm. If specified, the client request can only contain the specified headers. When unspecified, all the headers are used in the encryption algorithm. | diff --git a/docs/en/latest/plugins/jwt-auth.md b/docs/en/latest/plugins/jwt-auth.md index 124ae38577d1..f0b65ddcd3a4 100644 --- a/docs/en/latest/plugins/jwt-auth.md +++ b/docs/en/latest/plugins/jwt-auth.md @@ -42,9 +42,9 @@ For Consumer: | Name | Type | Required | Default | Valid values | Description | |---------------|---------|-------------------------------------------------------|---------|-----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | key | string | True | | | Unique key for a Consumer. | -| secret | string | False | | | The encryption key. If unspecified, auto generated in the background. | -| public_key | string | True if `RS256` or `ES256` is set for the `algorithm` attribute. | | | RSA or ECDSA public key. | -| private_key | string | True if `RS256` or `ES256` is set for the `algorithm` attribute. | | | RSA or ECDSA private key. | +| secret | string | False | | | The encryption key. If unspecified, auto generated in the background. 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. | +| private_key | string | True if `RS256` or `ES256` is set for the `algorithm` attribute. | | | RSA or ECDSA private 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. | | base64_secret | boolean | False | false | | Set to true if the secret is base64 encoded. | diff --git a/docs/en/latest/plugins/key-auth.md b/docs/en/latest/plugins/key-auth.md index ebac702bbb83..106301ce6bbd 100644 --- a/docs/en/latest/plugins/key-auth.md +++ b/docs/en/latest/plugins/key-auth.md @@ -39,7 +39,7 @@ For Consumer: | Name | Type | Requirement | Description | |------|--------|-------------|----------------------------| -| key | string | required | Unique key for a Consumer. | +| key | string | required | Unique key for a Consumer. This field supports saving the value in Secret Manager using the [APISIX Secret](../terminology/secret.md) resource. | NOTE: `encrypt_fields = {"key"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields). diff --git a/docs/en/latest/plugins/ldap-auth.md b/docs/en/latest/plugins/ldap-auth.md index 761c99b705f9..ebc87a494f6e 100644 --- a/docs/en/latest/plugins/ldap-auth.md +++ b/docs/en/latest/plugins/ldap-auth.md @@ -41,7 +41,7 @@ For Consumer: | Name | Type | Required | Description | | ------- | ------ | -------- | -------------------------------------------------------------------------------- | -| user_dn | string | True | User dn of the LDAP client. For example, `cn=user01,ou=users,dc=example,dc=org`. | +| user_dn | string | True | User dn of the LDAP client. For example, `cn=user01,ou=users,dc=example,dc=org`. This field supports saving the value in Secret Manager using the [APISIX Secret](../terminology/secret.md) resource. | For Route: diff --git a/docs/en/latest/plugins/wolf-rbac.md b/docs/en/latest/plugins/wolf-rbac.md index f7259f6885cf..b5280fd81779 100644 --- a/docs/en/latest/plugins/wolf-rbac.md +++ b/docs/en/latest/plugins/wolf-rbac.md @@ -36,7 +36,7 @@ The `wolf-rbac` Plugin provides a [role-based access control](https://en.wikiped | 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. | +| 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`. | ## API diff --git a/docs/zh/latest/plugins/basic-auth.md b/docs/zh/latest/plugins/basic-auth.md index ac8035152c73..e9451475f390 100644 --- a/docs/zh/latest/plugins/basic-auth.md +++ b/docs/zh/latest/plugins/basic-auth.md @@ -40,7 +40,7 @@ Consumer 端: | 名称 | 类型 | 必选项 | 描述 | | -------- | ------ | -----| ----------------------------------------------------------------------------------------------- | | username | string | 是 | Consumer 的用户名并且该用户名是唯一,如果多个 Consumer 使用了相同的 `username`,将会出现请求匹配异常。| -| password | string | 是 | 用户的密码。 | +| password | string | 是 | 用户的密码。该字段支持使用 [APISIX Secret](../terminology/secret.md) 资源,将值保存在 Secret Manager 中。 | 注意:schema 中还定义了 `encrypt_fields = {"password"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。 diff --git a/docs/zh/latest/plugins/hmac-auth.md b/docs/zh/latest/plugins/hmac-auth.md index 54c1d04548d4..dfd924f0e33d 100644 --- a/docs/zh/latest/plugins/hmac-auth.md +++ b/docs/zh/latest/plugins/hmac-auth.md @@ -38,7 +38,7 @@ description: 本文介绍了关于 Apache APISIX `hmac-auth` 插件的基本信 | 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | | ---------------- | ------------- | ------ | ------------- | ------------------------------------------| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | access_key | string | 是 | | | Consumer 的 `access_key` 必须是唯一的。如果不同 Consumer 使用了相同的 `access_key` ,将会出现请求匹配异常。 | -| secret_key | string | 是 | | | 与 `access_key` 配对使用。 | +| secret_key | string | 是 | | | 与 `access_key` 配对使用。该字段支持使用 [APISIX Secret](../terminology/secret.md) 资源,将值保存在 Secret Manager 中。 | | algorithm | string | 否 | "hmac-sha256" | ["hmac-sha1", "hmac-sha256", "hmac-sha512"] | 可以使用的加密算法。 | | clock_skew | integer | 否 | 0 | | 签名允许的时间偏移(以秒为单位)。比如允许时间偏移 10 秒钟,那么就应设置为 `10`。如果将其设置为 `0`,则表示表示跳过日期检查。 | | signed_headers | array[string] | 否 | | | 要在加密计算中使用的 headers 列表。指定后客户端请求只能在此范围内指定 headers,如果未指定,就会在所有客户端请求指定的 headers 加入加密计算。如: ["User-Agent", "Accept-Language", "x-custom-a"]。 | diff --git a/docs/zh/latest/plugins/jwt-auth.md b/docs/zh/latest/plugins/jwt-auth.md index 0f7196c5b8e1..c85c610a554d 100644 --- a/docs/zh/latest/plugins/jwt-auth.md +++ b/docs/zh/latest/plugins/jwt-auth.md @@ -42,9 +42,9 @@ Consumer 端: | 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | | ------------- | ------- | ----- | ------- | --------------------------- | ------------------------------------------------------------------------------------------------------------ | | key | string | 是 | | | Consumer 的 `access_key` 必须是唯一的。如果不同 Consumer 使用了相同的 `access_key` ,将会出现请求匹配异常。 | -| secret | string | 否 | | | 加密秘钥。如果未指定,后台将会自动生成。 | -| public_key | string | 否 | | | RSA 或 ECDSA 公钥, `algorithm` 属性选择 `RS256` 或 `ES256` 算法时必选。 | -| private_key | string | 否 | | | RSA 或 ECDSA 私钥, `algorithm` 属性选择 `RS256` 或 `ES256` 算法时必选。 | +| secret | string | 否 | | | 加密秘钥。如果未指定,后台将会自动生成。该字段支持使用 [APISIX Secret](../terminology/secret.md) 资源,将值保存在 Secret Manager 中。 | +| public_key | string | 否 | | | RSA 或 ECDSA 公钥, `algorithm` 属性选择 `RS256` 或 `ES256` 算法时必选。该字段支持使用 [APISIX Secret](../terminology/secret.md) 资源,将值保存在 Secret Manager 中。 | +| private_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 的超时时间。 | | base64_secret | boolean | 否 | false | | 当设置为 `true` 时,密钥为 base64 编码。 | diff --git a/docs/zh/latest/plugins/key-auth.md b/docs/zh/latest/plugins/key-auth.md index 23817fea09c2..17f71e1f1fe5 100644 --- a/docs/zh/latest/plugins/key-auth.md +++ b/docs/zh/latest/plugins/key-auth.md @@ -39,7 +39,7 @@ Consumer 端: | 名称 | 类型 | 必选项 | 描述 | | ---- | ------ | ------ | ------------------------------------------------------------------------------------------------------------- | -| key | string | 是 | 不同的 Consumer 应有不同的 `key`,它应当是唯一的。如果多个 Consumer 使用了相同的 `key`,将会出现请求匹配异常。 | +| key | string | 是 | 不同的 Consumer 应有不同的 `key`,它应当是唯一的。如果多个 Consumer 使用了相同的 `key`,将会出现请求匹配异常。该字段支持使用 [APISIX Secret](../terminology/secret.md) 资源,将值保存在 Secret Manager 中。 | 注意:schema 中还定义了 `encrypt_fields = {"key"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。 diff --git a/docs/zh/latest/plugins/ldap-auth.md b/docs/zh/latest/plugins/ldap-auth.md index 955d10ce6f2d..ee9ef81e42ea 100644 --- a/docs/zh/latest/plugins/ldap-auth.md +++ b/docs/zh/latest/plugins/ldap-auth.md @@ -39,7 +39,7 @@ Consumer 端: | 名称 | 类型 | 必选项 | 描述 | | ------- | ------ | -------- | -------------------------------------------------------------------------------- | -| user_dn | string | 是 | LDAP 客户端的 dn,例如:`cn=user01,ou=users,dc=example,dc=org`。 | +| user_dn | string | 是 | LDAP 客户端的 dn,例如:`cn=user01,ou=users,dc=example,dc=org`。该字段支持使用 [APISIX Secret](../terminology/secret.md) 资源,将值保存在 Secret Manager 中。 | Route 端: diff --git a/docs/zh/latest/plugins/wolf-rbac.md b/docs/zh/latest/plugins/wolf-rbac.md index 0c9b25137d0f..af82fc7a8a08 100644 --- a/docs/zh/latest/plugins/wolf-rbac.md +++ b/docs/zh/latest/plugins/wolf-rbac.md @@ -36,7 +36,7 @@ description: 本文介绍了关于 Apache APISIX `wolf-rbac` 插件的基本信 | 名称 | 类型 | 必选项 | 默认值 | 描述 | | ------------- | ------ | ------ | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | | server | string | 否 | "http://127.0.0.1:12180" | `wolf-server` 的服务地址。 | -| appid | string | 否 | "unset" | 在 `wolf-console` 中已经添加的应用 id。 | +| 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`。| ## 接口 diff --git a/t/plugin/basic-auth.t b/t/plugin/basic-auth.t index 64ae5dd04a37..533dda6266b0 100644 --- a/t/plugin/basic-auth.t +++ b/t/plugin/basic-auth.t @@ -452,3 +452,91 @@ GET /echo Authorization: Basic Zm9vOmJhcg== --- response_headers Authorization: Basic Zm9vOmJhcg== + + + +=== TEST 22: set basic-auth conf: password uses secret ref +--- request +GET /t +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + -- put secret vault config + local code, body = t('/apisix/admin/secrets/vault/test1', + ngx.HTTP_PUT, + [[{ + "uri": "http://127.0.0.1:8200", + "prefix" : "kv/apisix", + "token" : "root" + }]] + ) + + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + -- change consumer with secrets ref: vault + code, body = t('/apisix/admin/consumers', + ngx.HTTP_PUT, + [[{ + "username": "foo", + "plugins": { + "basic-auth": { + "username": "foo", + "password": "$secret://vault/test1/foo/passwd" + } + } + }]] + ) + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + -- set route + code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "basic-auth": { + "hide_credentials": false + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/echo" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 23: store secret into vault +--- exec +VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/foo passwd=bar +--- response_body +Success! Data written to: kv/apisix/foo + + + +=== TEST 24: verify Authorization with foo/bar, request header should not hidden +--- request +GET /echo +--- more_headers +Authorization: Basic Zm9vOmJhcg== +--- response_headers +Authorization: Basic Zm9vOmJhcg== diff --git a/t/plugin/hmac-auth4.t b/t/plugin/hmac-auth4.t new file mode 100644 index 000000000000..2316e07ae6d2 --- /dev/null +++ b/t/plugin/hmac-auth4.t @@ -0,0 +1,168 @@ +# +# 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_shuffle(); +no_root_location(); + +add_block_preprocessor(sub { + my ($block) = @_; + + if (!$block->request) { + $block->set_value("request", "GET /t"); + } + + if (!$block->no_error_log && !$block->error_log) { + $block->set_value("no_error_log", "[error]\n[alert]"); + } +}); + +run_tests; + +__DATA__ + +=== TEST 1: set hmac-auth conf: secret_key uses secret ref +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + -- put secret vault config + local code, body = t('/apisix/admin/secrets/vault/test1', + ngx.HTTP_PUT, + [[{ + "uri": "http://127.0.0.1:8200", + "prefix" : "kv/apisix", + "token" : "root" + }]] + ) + + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + -- change consumer with secrets ref: vault + code, body = t('/apisix/admin/consumers', + ngx.HTTP_PUT, + [[{ + "username": "jack", + "plugins": { + "hmac-auth": { + "access_key": "my-access-key", + "secret_key": "$secret://vault/test1/jack/secret_key" + } + } + }]] + ) + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + -- set route + code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "hmac-auth": {} + }, + "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 2: store secret into vault +--- exec +VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/jack secret_key=my-secret-key +--- response_body +Success! Data written to: kv/apisix/jack + + + +=== TEST 3: verify: ok +--- config +location /t { + content_by_lua_block { + local ngx_time = ngx.time + local ngx_http_time = ngx.http_time + local core = require("apisix.core") + local t = require("lib.test_admin") + local hmac = require("resty.hmac") + local ngx_encode_base64 = ngx.encode_base64 + + local secret_key = "my-secret-key" + local timestamp = ngx_time() + local gmt = ngx_http_time(timestamp) + local access_key = "my-access-key" + local custom_header_a = "asld$%dfasf" + local custom_header_b = "23879fmsldfk" + + local signing_string = { + "GET", + "/hello", + "", + access_key, + gmt, + "x-custom-header-a:" .. custom_header_a, + "x-custom-header-b:" .. custom_header_b + } + signing_string = core.table.concat(signing_string, "\n") .. "\n" + core.log.info("signing_string:", signing_string) + + local signature = hmac:new(secret_key, hmac.ALGOS.SHA256):final(signing_string) + core.log.info("signature:", ngx_encode_base64(signature)) + local headers = {} + headers["X-HMAC-SIGNATURE"] = ngx_encode_base64(signature) + headers["X-HMAC-ALGORITHM"] = "hmac-sha256" + headers["Date"] = gmt + headers["X-HMAC-ACCESS-KEY"] = access_key + headers["X-HMAC-SIGNED-HEADERS"] = "x-custom-header-a;x-custom-header-b" + headers["x-custom-header-a"] = custom_header_a + headers["x-custom-header-b"] = custom_header_b + + local code, body = t.test('/hello', + ngx.HTTP_GET, + "", + nil, + headers + ) + + ngx.status = code + ngx.say(body) + } +} +--- response_body +passed diff --git a/t/plugin/jwt-auth3.t b/t/plugin/jwt-auth3.t index 3e431232f406..ac4587de0ed7 100755 --- a/t/plugin/jwt-auth3.t +++ b/t/plugin/jwt-auth3.t @@ -442,3 +442,201 @@ IeQmD/K+DClZMqSrliUzUqJnCPCzy6kCIAekDsRh/UF4ONjAJkKuLedDUfL3rNFb YvIufaZvBa8f+E/9CANlVhm5wKAyM8N8GJsiCyEG -----END RSA PRIVATE KEY----- HrMHUvE9Esvn7GnZ+vAynaIg/8wlB3r0zm0htmnwofYPZeBpLnpW3iN9UtQG4ZIBYRZih6EBuRK8W3Kychw/SgjIFuzVeTFowBCUfd1wZ4Q+frUOLZ0Xmkh8j3yHUprnh+d9PA8EHCEapdkWY3psJj6rTgrREzjDEVf/TV3EjjfgG16ih5/c3TChApLXwfEwfBp5APSf7kzMccCRbA4bXvMDsQSQAwVsRD8cjJkSdHTvuzfg1g8xoCy4I05DsMM8CybJAd+BDZnJxhrGIQaItu5/0XQJy+uy/niOpzYYN+NDX+8fl65VUxdUtqXF82ChRlmGP3+zKN7epufAsL/36pHOnS73Q7WBKRxyyA16BEBk0wK7rI+KemBfG5YFXjcBnPkxYssSudqhmlcr6e5Tl0LhVj/BIj94fVE3/EJ+NO3BJMrlhjorilrQKAsiCWujWSqAK7gtAp3YEO//yOygh/p8gh22NdIV0ykGAx4QNKINUgdgh+g8DdykNGLGStH8TPUs8GmzV7nxvw/0cbiocLps6uk0VjjVUqUAvOdwpbiRwv6effPUB6cxW3G6QllBbTP8I+eoFIRfYd6cFJPpX1AtISfNZw459WarwZmHrZGOQU4iKlyl2yLcKY634Fx5JykUY5YP+MYYDHbIcD2gxA== + + + +=== TEST 16: set jwt-auth conf: secret uses secret ref +--- request +GET /t +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + -- put secret vault config + local code, body = t('/apisix/admin/secrets/vault/test1', + ngx.HTTP_PUT, + [[{ + "uri": "http://127.0.0.1:8200", + "prefix" : "kv/apisix", + "token" : "root" + }]] + ) + + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + -- change consumer with secrets ref: vault + code, body = t('/apisix/admin/consumers', + ngx.HTTP_PUT, + [[{ + "username": "jack", + "plugins": { + "jwt-auth": { + "key": "user-key", + "secret": "$secret://vault/test1/jack/secret" + } + } + }]] + ) + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + -- set route + code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "jwt-auth": { + "header": "jwt-header", + "query": "jwt-query", + "cookie": "jwt-cookie", + "hide_credentials": false + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/echo" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 17: store secret into vault +--- exec +VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/jack secret=my-secret-key +--- response_body +Success! Data written to: kv/apisix/jack + + + +=== TEST 18: verify (in header) not hiding credentials +--- request +GET /echo +--- more_headers +jwt-header: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs +--- response_headers +jwt-header: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs + + + +=== TEST 19: store rsa key pairs and secret into vault from local filesystem +--- exec +VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/rsa1 secret=$3nsitiv3-c8d3 public_key=@t/certs/public.pem private_key=@t/certs/private.pem +--- response_body +Success! Data written to: kv/apisix/rsa1 + + + +=== TEST 20: create consumer for RS256 algorithm with private/public key fetched from vault and public key in consumer schema +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + -- enable jwt auth plugin using admin api + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "jwt-auth": {} + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + -- create public API route (jwt-auth sign) + local code, body = t('/apisix/admin/routes/2', + ngx.HTTP_PUT, + [[{ + "plugins": { + "public-api": {} + }, + "uri": "/apisix/plugin/jwt/sign" + }]] + ) + + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + local code, body = t('/apisix/admin/consumers', + ngx.HTTP_PUT, + [[{ + "username": "john", + "plugins": { + "jwt-auth": { + "key": "rsa1", + "algorithm": "RS256", + "secret": "$secret://vault/test1/rsa1/secret", + "public_key": "$secret://vault/test1/rsa1/public_key", + "private_key": "$secret://vault/test1/rsa1/private_key" + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 21: sign a jwt with with rsa key pair and access /hello +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, err, sign = t('/apisix/plugin/jwt/sign?key=rsa1', + ngx.HTTP_GET + ) + + if code > 200 then + ngx.status = code + ngx.say(err) + return + end + + local code, _, res = t('/hello?jwt=' .. sign, + ngx.HTTP_GET + ) + if code >= 300 then + ngx.status = code + end + ngx.print(res) + } + } +--- response_body +hello world diff --git a/t/plugin/key-auth.t b/t/plugin/key-auth.t index dd0d70f50113..850a65e183e9 100644 --- a/t/plugin/key-auth.t +++ b/t/plugin/key-auth.t @@ -578,13 +578,12 @@ auth: authone -=== TEST 28: put secret vault config ---- request -GET /t +=== TEST 28: set key-auth conf: key uses secret ref --- config location /t { content_by_lua_block { local t = require("lib.test_admin").test + -- put secret vault config local etcd = require("apisix.core.etcd") local code, body = t('/apisix/admin/secrets/vault/test1', ngx.HTTP_PUT, @@ -592,38 +591,22 @@ GET /t "uri": "http://127.0.0.1:8200", "prefix" : "kv/apisix", "token" : "root" - }]], - [[{ - "value": { - "uri": "http://127.0.0.1:8200", - "prefix" : "kv/apisix", - "token" : "root" - }, - "key": "/apisix/secrets/vault/test1" }]] ) - ngx.status = code - ngx.say(body) - } - } ---- response_body -passed - - + if code >= 300 then + ngx.status = code + return ngx.say(body) + end -=== TEST 29: change consumer with secrets ref: vault ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test + -- change consumer with secrets ref: vault local code, body = t('/apisix/admin/consumers', ngx.HTTP_PUT, [[{ "username": "jack", "plugins": { "key-auth": { - "key": "$secret://vault/test1/jack/auth-key" + "key": "$secret://vault/test1/jack/key" } } }]] @@ -642,15 +625,15 @@ passed -=== TEST 30: store secret into vault +=== TEST 29: store secret into vault --- exec -VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/jack auth-key=authtwo +VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/jack key=authtwo --- response_body Success! Data written to: kv/apisix/jack -=== TEST 31: verify auth request +=== TEST 30: verify auth request --- request GET /hello?auth=authtwo --- response_args diff --git a/t/plugin/ldap-auth.t b/t/plugin/ldap-auth.t index 1af8291771e4..b8f3936ef411 100644 --- a/t/plugin/ldap-auth.t +++ b/t/plugin/ldap-auth.t @@ -440,3 +440,94 @@ Authorization: Basic dXNlcjAxOnBhc3N3b3JkMQ== hello world --- error_log find consumer user01 + + + +=== TEST 21: set ldap-auth conf: user_dn uses secret ref +--- request +GET /t +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + -- put secret vault config + local code, body = t('/apisix/admin/secrets/vault/test1', + ngx.HTTP_PUT, + [[{ + "uri": "http://127.0.0.1:8200", + "prefix" : "kv/apisix", + "token" : "root" + }]] + ) + + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + -- change consumer with secrets ref: vault + code, body = t('/apisix/admin/consumers', + ngx.HTTP_PUT, + [[{ + "username": "user01", + "plugins": { + "ldap-auth": { + "user_dn": "$secret://vault/test1/user01/user_dn" + } + } + }]] + ) + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + -- set route + code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "ldap-auth": { + "base_dn": "ou=users,dc=example,dc=org", + "ldap_uri": "127.0.0.1:1389", + "uid": "cn" + } + }, + "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 22: store secret into vault +--- exec +VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/user01 user_dn="cn=user01,ou=users,dc=example,dc=org" +--- response_body +Success! Data written to: kv/apisix/user01 + + + +=== TEST 23: verify +--- request +GET /hello +--- more_headers +Authorization: Basic dXNlcjAxOnBhc3N3b3JkMQ== +--- response_body +hello world +--- error_log +find consumer user01 diff --git a/t/plugin/wolf-rbac.t b/t/plugin/wolf-rbac.t index 2780d26b46f3..af3be4524206 100644 --- a/t/plugin/wolf-rbac.t +++ b/t/plugin/wolf-rbac.t @@ -546,3 +546,76 @@ qr/ERR_TOKEN_INVALID */ ERR_TOKEN_INVALID ERR_TOKEN_INVALID ERR_TOKEN_INVALID + + + +=== TEST 31: set hmac-auth conf: appid uses secret ref +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + -- put secret vault config + local code, body = t('/apisix/admin/secrets/vault/test1', + ngx.HTTP_PUT, + [[{ + "uri": "http://127.0.0.1:8200", + "prefix" : "kv/apisix", + "token" : "root" + }]] + ) + + if code >= 300 then + ngx.status = code + return ngx.say(body) + end + + code, body = t('/apisix/admin/consumers', + ngx.HTTP_PUT, + [[{ + "username": "wolf_rbac_unit_test", + "plugins": { + "wolf-rbac": { + "appid": "$secret://vault/test1/wolf_rbac_unit_test/appid", + "server": "http://127.0.0.1:1982" + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 32: store secret into vault +--- exec +VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/wolf_rbac_unit_test appid=wolf-rbac-app +--- response_body +Success! Data written to: kv/apisix/wolf_rbac_unit_test + + + +=== TEST 33: login successfully +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/plugin/wolf-rbac/login', + ngx.HTTP_POST, + [[ + {"appid": "wolf-rbac-app", "username": "admin","password": "123456"} + ]], + [[ + {"rbac_token":"V1#wolf-rbac-app#wolf-rbac-token","user_info":{"nickname":"administrator","username":"admin","id":"100"}} + ]], + {["Content-Type"] = "application/json"} + ) + ngx.status = code + } + }