diff --git a/apisix/plugins/openid-connect.lua b/apisix/plugins/openid-connect.lua index b472feca0159..976c606b6bfc 100644 --- a/apisix/plugins/openid-connect.lua +++ b/apisix/plugins/openid-connect.lua @@ -213,7 +213,7 @@ local function introspect(ctx, conf) -- Token successfully validated. local method = (conf.public_key and "public_key") or (conf.use_jwks and "jwks") core.log.debug("token validate successfully by ", method) - return res, err, token, nil + return res, err, token, res else -- Validate token against introspection endpoint. -- TODO: Same as above for public key validation. diff --git a/t/plugin/openid-connect.t b/t/plugin/openid-connect.t index 9337e4235d18..d8be6759890d 100644 --- a/t/plugin/openid-connect.t +++ b/t/plugin/openid-connect.t @@ -593,13 +593,14 @@ passed --- request GET /uri HTTP/1.1 --- more_headers -Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhMSI6IkRhdGEgMSIsImlhdCI6MTU4NTEyMjUwMiwiZXhwIjoxOTAwNjk4NTAyLCJhdWQiOiJodHRwOi8vbXlzb2Z0Y29ycC5pbiIsImlzcyI6Ik15c29mdCBjb3JwIiwic3ViIjoic29tZUB1c2VyLmNvbSJ9.u1ISx7JbuK_GFRIUqIMP175FqXRyF9V7y86480Q4N3jNxs3ePbc51TFtIHDrKttstU4Tub28PYVSlr-HXfjo7w ---- response_body +Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhMSI6IkRhdGEgMSIsImlhdCI6MTU4NTEyMjUwMiwiZXhwIjoxOTAwNjk4NTAyLCJhdWQiOiJodHRwOi8vbXlzb2Z0Y29ycC5pbiIsImlzcyI6Ik15c29mdCBjb3JwIiwic3ViIjoic29tZUB1c2VyLmNvbSJ9.Vq_sBN7nH67vMDbiJE01EP4hvJYE_5ju6izjkOX8pF5OS4g2RWKWpL6h6-b0tTkCzG4JD5BEl13LWW-Gxxw0i9vEK0FLg_kC_kZLYB8WuQ6B9B9YwzmZ3OLbgnYzt_VD7D-7psEbwapJl5hbFsIjDgOAEx-UCmjUcl2frZxZavG2LUiEGs9Ri7KqOZmTLgNDMWfeWh1t1LyD0_b-eTInbasVtKQxMlb5kR0Ln_Qg5092L-irJ7dqaZma7HItCnzXJROdqJEsMIBAYRwDGa_w5kIACeMOdU85QKtMHzOenYFkm6zh_s59ndziTctKMz196Y8AL08xuTi6d1gEWpM92A +--- response_body_like uri: /uri authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhMSI6IkRhdGEgMSIsImlhdCI6MTU4NTEyMjUwMiwiZXhwIjoxOTAwNjk4NTAyLCJhdWQiOiJodHRwOi8vbXlzb2Z0Y29ycC5pbiIsImlzcyI6Ik15c29mdCBjb3JwIiwic3ViIjoic29tZUB1c2VyLmNvbSJ9.u1ISx7JbuK_GFRIUqIMP175FqXRyF9V7y86480Q4N3jNxs3ePbc51TFtIHDrKttstU4Tub28PYVSlr-HXfjo7w host: localhost x-access-token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhMSI6IkRhdGEgMSIsImlhdCI6MTU4NTEyMjUwMiwiZXhwIjoxOTAwNjk4NTAyLCJhdWQiOiJodHRwOi8vbXlzb2Z0Y29ycC5pbiIsImlzcyI6Ik15c29mdCBjb3JwIiwic3ViIjoic29tZUB1c2VyLmNvbSJ9.u1ISx7JbuK_GFRIUqIMP175FqXRyF9V7y86480Q4N3jNxs3ePbc51TFtIHDrKttstU4Tub28PYVSlr-HXfjo7w x-real-ip: 127.0.0.1 +x-userinfo: ey.* --- no_error_log [error] --- error_code: 200 @@ -1263,3 +1264,115 @@ true --- error_code: 302 --- no_error_log [error] + + + +=== TEST 32: set use_jwks and set_userinfo_header to validate "x-userinfo" in request 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": { + "openid-connect": { + "client_id": "course_management", + "client_secret": "d1ec69e9-55d2-4109-a3ea-befa071579d5", + "discovery": "http://127.0.0.1:8090/auth/realms/University/.well-known/openid-configuration", + "realm": "University", + "bearer_only": true, + "access_token_in_authorization_header": true, + "set_userinfo_header": true, + "use_jwks": true, + "redirect_uri": "http://localhost:3000", + "ssl_verify": false, + "timeout": 10, + "introspection_endpoint_auth_method": "client_secret_post", + "introspection_endpoint": "http://127.0.0.1:8090/auth/realms/University/protocol/openid-connect/token/introspect" + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/*" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 33: Access route to validate "x-userinfo" in request 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:8090/auth/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 .. "/uri" + local res, err = httpc:request_uri(uri, { + method = "GET", + headers = { + ["Authorization"] = "Bearer " .. body["access_token"] + } + }) + + if not res then + -- No response, must be an error. + ngx.status = 500 + ngx.say(err) + return + elseif res.status ~= 200 then + -- Not a valid response. + -- Use 500 to indicate error. + ngx.status = 500 + ngx.say("Invoking the original URI didn't return the expected result.") + return + end + + ngx.status = res.status + ngx.say(res.body) + + else + -- Response from Keycloak not ok. + ngx.say(false) + end + } + } +--- response_body_like +x-userinfo: ey.* +>>>>>>> 4346b0b2... fix(openid-connect): return userinfo when use_jwks is true (#8347)