diff --git a/gateway/src/apicast/policy/jwt_claim_check/jwt_claim_check.lua b/gateway/src/apicast/policy/jwt_claim_check/jwt_claim_check.lua index 859782e8c..0f95fdb3c 100644 --- a/gateway/src/apicast/policy/jwt_claim_check/jwt_claim_check.lua +++ b/gateway/src/apicast/policy/jwt_claim_check/jwt_claim_check.lua @@ -5,6 +5,7 @@ local Condition = require('apicast.conditions.condition') local MappingRule = require('apicast.mapping_rule') local Operation = require('apicast.conditions.operation') local TemplateString = require('apicast.template_string') +local escape = require("resty.http.uri_escape") local ipairs = ipairs @@ -58,6 +59,10 @@ end local function is_rule_denied_request(rule, context) local uri = context:get_uri() + -- URI need to be escaped to be able to match values with special characters + -- (like spaces) + -- Example: if URI is `/foo /bar` it will be translated to `/foo%20/bar` + local escaped_uri = escape.escape_uri(uri) local request_method = ngx.req.get_method() local resource = rule.resource:render(context) @@ -71,7 +76,7 @@ local function is_rule_denied_request(rule, context) -- the name of the metric is irrelevant metric_system_name = 'hits' }) - if mapping_rule:matches(request_method, uri) then + if mapping_rule:matches(request_method, escaped_uri) then mapping_rule_match = true break end diff --git a/t/apicast-policy-jwt-claim-check.t b/t/apicast-policy-jwt-claim-check.t index 7d4b0c8be..34773f03e 100644 --- a/t/apicast-policy-jwt-claim-check.t +++ b/t/apicast-policy-jwt-claim-check.t @@ -564,3 +564,84 @@ the URI is not longer valid at all, and JWT is not expected to work correctly. ["yay, api backend\n","Request blocked due to JWT claim policy\n"] --- no_error_log [error] + + + +=== TEST 8: JWT claim reject request with invalid token and URI contain special characters +--- backend + location /transactions/oauth_authrep.xml { + content_by_lua_block { + ngx.exit(200) + } + } + +--- configuration +{ + "oidc": [ + { + "issuer": "https://example.com/auth/realms/apicast", + "config": { "id_token_signing_alg_values_supported": [ "RS256" ] }, + "keys": { "somekid": { "pem": "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALClz96cDQ965ENYMfZzG+Acu25lpx2K\nNpAALBQ+catCA59us7+uLY5rjQR6SOgZpCz5PJiKNAdRPDJMXSmXqM0CAwEAAQ==\n-----END PUBLIC KEY-----", "alg": "RS256" } } + } + ], + "services": [ + { + "id": 42, + "backend_version": "oauth", + "backend_authentication_type": "service_token", + "backend_authentication_value": "token-value", + "proxy": { + "authentication_method": "oidc", + "oidc_issuer_endpoint": "https://example.com/auth/realms/apicast", + "api_backend": "http://test:$TEST_NGINX_SERVER_PORT/", + "proxy_rules": [ + { "pattern": "/groups/{groupID}$", "http_method": "GET", "metric_system_name": "hits", "delta": 1 } + ], + "policy_chain": [ + { + "name": "apicast.policy.jwt_claim_check", + "configuration": { + "rules" : [{ + "operations": [ + {"op": "==", "jwt_claim": "foo", "jwt_claim_type": "plain", "value": "1"} + ], + "combine_op": "and", + "methods": ["GET"], + "resource": "/groups/{groupdID}$" + }] + } + }, + { "name": "apicast.policy.apicast" } + ] + } + } + ] +} +--- upstream + location /groups { + content_by_lua_block { + ngx.say('yay, api backend'); + } + } +--- request eval +[ + "GET /groups/%2020", + "GET /groups/%2020%0A30" +] +--- more_headers eval +::authorization_bearer_jwt('audience', { + realm_access => { + roles => [ 'director' ] + }, + foo => "invalid", +}, 'somekid') +--- error_code eval +[403, 403] +--- response_body eval +[ + "Request blocked due to JWT claim policy\x{0a}", + "Request blocked due to JWT claim policy\x{0a}" +] +--- no_error_log +[error] +