diff --git a/apisix/plugins/openid-connect.lua b/apisix/plugins/openid-connect.lua index a64ba2fa9122..357328665ff2 100644 --- a/apisix/plugins/openid-connect.lua +++ b/apisix/plugins/openid-connect.lua @@ -481,7 +481,7 @@ function _M.rewrite(plugin_conf, ctx) local response, err, session, _ - if conf.bearer_only or conf.introspection_endpoint or conf.public_key then + if conf.bearer_only or conf.introspection_endpoint or conf.public_key or conf.use_jwks then -- An introspection endpoint or a public key has been configured. Try to -- validate the access token from the request, if it is present in a -- request header. Otherwise, return a nil response. See below for diff --git a/t/plugin/openid-connect.t b/t/plugin/openid-connect.t index f539a5fba8d4..6a883486724a 100644 --- a/t/plugin/openid-connect.t +++ b/t/plugin/openid-connect.t @@ -1425,3 +1425,107 @@ passed --- response_body true --- error_code: 302 + + + +=== TEST 38: Update plugin config to use_jwk and bear_only false +--- 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": { + "openid-connect": { + "client_id": "course_management", + "client_secret": "d1ec69e9-55d2-4109-a3ea-befa071579d5", + "discovery": "http://127.0.0.1:8080/realms/University/.well-known/openid-configuration", + "redirect_uri": "http://localhost:3000", + "ssl_verify": false, + "timeout": 10, + "bearer_only": false, + "use_jwks": true, + "realm": "University", + "introspection_endpoint_auth_method": "client_secret_post", + "introspection_endpoint": "http://127.0.0.1:8080/realms/University/protocol/openid-connect/token/introspect" + } + }, + "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 39: Test that jwt with bearer_only false still allows a valid Authorization header +--- config + location /t { + content_by_lua_block { + -- Obtain valid access token from Keycloak using known username and password. + local json_decode = require("toolkit.json").decode + local http = require "resty.http" + local httpc = http.new() + local uri = "http://127.0.0.1:8080/realms/University/protocol/openid-connect/token" + local res, err = httpc:request_uri(uri, { + method = "POST", + body = "grant_type=password&client_id=course_management&client_secret=d1ec69e9-55d2-4109-a3ea-befa071579d5&username=teacher@gmail.com&password=123456", + headers = { + ["Content-Type"] = "application/x-www-form-urlencoded" + } + }) + + -- Check response from keycloak and fail quickly if there's no response. + if not res then + ngx.say(err) + return + end + + -- Check if response code was ok. + if res.status == 200 then + -- Get access token from JSON response body. + local body = json_decode(res.body) + local accessToken = body["access_token"] + + -- Access route using access token. Should work. + uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello" + local res, err = httpc:request_uri(uri, { + method = "GET", + headers = { + ["Authorization"] = "Bearer " .. body["access_token"] + } + }) + + if res.status == 200 then + -- Route accessed successfully. + ngx.say(true) + else + -- Couldn't access route. + ngx.say(false) + end + else + -- Response from Keycloak not ok. + ngx.say(false) + end + } + } +--- response_body +true +--- grep_error_log eval +qr/token validate successfully by \w+/ +--- grep_error_log_out +token validate successfully by jwks