diff --git a/apisix/plugins/authz-keycloak.lua b/apisix/plugins/authz-keycloak.lua index 34a0533326f9..400e56b49ae8 100644 --- a/apisix/plugins/authz-keycloak.lua +++ b/apisix/plugins/authz-keycloak.lua @@ -768,7 +768,7 @@ function _M.access(conf, ctx) local headers = core.request.headers(ctx) local need_grant_token = conf.password_grant_token_generation_incoming_uri and ctx.var.request_uri == conf.password_grant_token_generation_incoming_uri and - headers["content-type"] == "application/x-www-form-urlencoded" and + sub_str(headers["content-type"], 1, 33) == "application/x-www-form-urlencoded" and core.request.get_method() == "POST" if need_grant_token then return generate_token_using_password_grant(conf,ctx) diff --git a/docs/en/latest/plugins/authz-keycloak.md b/docs/en/latest/plugins/authz-keycloak.md index bb968e6f7d71..d0d2b2deeb23 100644 --- a/docs/en/latest/plugins/authz-keycloak.md +++ b/docs/en/latest/plugins/authz-keycloak.md @@ -143,6 +143,8 @@ curl --location --request POST 'http://127.0.0.1:9080/api/token' \ --data-urlencode 'password=' ``` +Note: For the value of the `Content-Type` header, it also support the parameterized form which defind in the section [3.1.1.5](https://www.rfc-editor.org/rfc/rfc7231#section-3.1.1.5) of [RFC7231](https://www.rfc-editor.org/rfc/rfc7231). For example `Content-Type: application/json; charset=utf-8`. + ## Enable Plugin The example below shows how you can enable the `authz-keycloak` Plugin on a specific Route. `${realm}` represents the realm name in Keycloak. diff --git a/docs/zh/latest/plugins/authz-keycloak.md b/docs/zh/latest/plugins/authz-keycloak.md index 576f29bd3633..eece05772df0 100644 --- a/docs/zh/latest/plugins/authz-keycloak.md +++ b/docs/zh/latest/plugins/authz-keycloak.md @@ -127,6 +127,8 @@ description: 本文介绍了关于 Apache APISIX `authz-keycloak` 插件的基 --data-urlencode 'password=' ``` + 注意:对于`Content-Type`头的值,此插件也支持参数化的形式(具体定义在[RFC7231](https://www.rfc-editor.org/rfc/rfc7231)的第[3.1.1.5](https://www.rfc-editor.org/rfc/rfc7231#section-3.1.1.5)小节)。具体示例`Content-Type: application/json; charset=utf-8`。 + ## 如何启用 以下示例为你展示了如何在指定 Route 中启用 `authz-keycloak` 插件,其中 `${realm}` 是 Keycloak 中的 `realm` 名称: diff --git a/t/plugin/authz-keycloak4.t b/t/plugin/authz-keycloak4.t index 60aea47f05c4..45edeca3e67b 100644 --- a/t/plugin/authz-keycloak4.t +++ b/t/plugin/authz-keycloak4.t @@ -179,7 +179,71 @@ success -=== TEST 4: set invalid client_secret as a reference to env variable +=== TEST 4: add charset directive in content-type header +--- 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": { + "authz-keycloak": { + "token_endpoint": "https://127.0.0.1:8443/realms/University/protocol/openid-connect/token", + "permissions": ["course_resource"], + "client_id": "course_management", + "client_secret": "$env://CLIENT_SECRET", + "grant_type": "urn:ietf:params:oauth:grant-type:uma-ticket", + "timeout": 3000, + "ssl_verify": false, + "password_grant_token_generation_incoming_uri": "/api/token" + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1982": 1 + }, + "type": "roundrobin" + }, + "uri": "/api/token" + }]] + ) + + if code >= 300 then + ngx.status = code + return + end + + local json_decode = require("toolkit.json").decode + local http = require "resty.http" + local httpc = http.new() + local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/api/token" + local headers = { + ["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8", + } + + -- no username + local res, err = httpc:request_uri(uri, { + method = "POST", + headers = headers, + body = ngx.encode_args({ + username = "teacher@gmail.com", + password = "123456", + }), + }) + if res.status == 200 then + ngx.print("success\n") + end + } + } +--- request +GET /t +--- response_body +success + + + +=== TEST 5: set invalid client_secret as a reference to env variable --- config location /t { content_by_lua_block {