Skip to content

Commit cdaf824

Browse files
committed
try to read introspection_endpoint from discovery as fallback
see zmartzone#255 Signed-off-by: Stefan Bodewig <stefan.bodewig@innoq.com>
1 parent d7712be commit cdaf824

File tree

5 files changed

+67
-1
lines changed

5 files changed

+67
-1
lines changed

ChangeLog

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
- added unauth_action='deny' to reject unauthenticated requests rather
33
than start the authorization code grant flow; see #271; based on
44
suggested change by @nmaniwa
5+
- read introspection_endpoint from discovery document when present; see #255
56

67
05/01/2019
78
- performance enhancement by caching the result of ngx.req.get_headers

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,14 @@ http {
490490
access_by_lua '
491491
492492
local opts = {
493+
-- sets the URI of the introspection endpoint
493494
introspection_endpoint="https://localhost:9031/oauth2/introspect",
495+
496+
-- alternatively if your OAuth2 Provider provides a discovery document that contains the
497+
-- introspection_endpoint claim you can leave the introspection_endpoint option
498+
-- unset and instead use
499+
-- discovery = "https://my-oauth2-provider/.well-known/oauth-authorization-server",
500+
494501
client_id="admin",
495502
client_secret="demo-password",
496503
ssl_verify = "no",

lib/resty/openidc.lua

+16-1
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,10 @@ function openidc.call_token_endpoint(opts, endpoint, body, auth, endpoint_name,
414414
local ignore_body_on_success = ignore_body_on_success or false
415415

416416
local ep_name = endpoint_name or 'token'
417+
if not endpoint then
418+
return nil, 'no endpoint URI for ' .. ep_name
419+
end
420+
417421
local headers = {
418422
["Content-Type"] = "application/x-www-form-urlencoded"
419423
}
@@ -1603,7 +1607,18 @@ function openidc.introspect(opts)
16031607
end
16041608

16051609
-- call the introspection endpoint
1606-
json, err = openidc.call_token_endpoint(opts, opts.introspection_endpoint, body, opts.introspection_endpoint_auth_method, "introspection")
1610+
local introspection_endpoint = opts.introspection_endpoint
1611+
if not introspection_endpoint then
1612+
err = openidc_ensure_discovered_data(opts)
1613+
if err then
1614+
return nil, "opts.introspection_endpoint not said and " .. err
1615+
end
1616+
local endpoint = opts.discovery and opts.discovery.introspection_endpoint
1617+
if endpoint then
1618+
introspection_endpoint = endpoint
1619+
end
1620+
end
1621+
json, err = openidc.call_token_endpoint(opts, introspection_endpoint, body, opts.introspection_endpoint_auth_method, "introspection")
16071622

16081623

16091624
if not json then

tests/spec/introspection_spec.lua

+38
Original file line numberDiff line numberDiff line change
@@ -526,3 +526,41 @@ describe("when a request_decorator has been specified when calling the token end
526526
end)
527527
end)
528528

529+
describe("when introspection endpoint hasn't been specified", function()
530+
test_support.start_server({
531+
remove_introspection_config_keys = { 'introspection_endpoint' }
532+
})
533+
teardown(test_support.stop_server)
534+
local jwt = test_support.trim(http.request("http://127.0.0.1/jwt"))
535+
local _, status = http.request({
536+
url = "http://127.0.0.1/introspect",
537+
headers = { authorization = "Bearer " .. jwt }
538+
})
539+
it("the response is invalid", function()
540+
assert.are.equals(401, status)
541+
end)
542+
it("an error has been logged", function()
543+
assert.error_log_contains("Introspection error: no endpoint URI for introspection")
544+
end)
545+
end)
546+
547+
describe("when introspection endpoint hasn't been specified but discovery doc provides introspection_endpoint claim", function()
548+
test_support.start_server({
549+
remove_introspection_config_keys = { 'introspection_endpoint' },
550+
introspection_opts = {
551+
discovery = {
552+
introspection_endpoint = "http://127.0.0.1/introspection"
553+
}
554+
},
555+
})
556+
teardown(test_support.stop_server)
557+
local jwt = test_support.trim(http.request("http://127.0.0.1/jwt"))
558+
local _, status = http.request({
559+
url = "http://127.0.0.1/introspect",
560+
headers = { authorization = "Bearer " .. jwt }
561+
})
562+
it("the response is valid", function()
563+
assert.are.equals(200, status)
564+
end)
565+
end)
566+

tests/spec/test_support.lua

+5
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,9 @@ local function write_config(out, custom_config)
450450
for _, k in ipairs(custom_config["remove_oidc_config_keys"] or {}) do
451451
oidc_config[k] = nil
452452
end
453+
for _, k in ipairs(custom_config["remove_introspection_config_keys"] or {}) do
454+
introspection_opts[k] = nil
455+
end
453456
local config = DEFAULT_CONFIG_TEMPLATE
454457
:gsub("OIDC_CONFIG", serpent.block(oidc_config, {comment = false }))
455458
:gsub("TOKEN_HEADER", serpent.block(token_header, {comment = false }))
@@ -501,6 +504,8 @@ end
501504
-- the introspection endpoint
502505
-- - remove_introspection_claims is an array of claims to remove from the introspection response
503506
-- - introspection_opts is a table containing options that are accepted by oidc.introspect
507+
-- - remove_introspection_config_keys is an array of claims to remove from the introspection
508+
-- configuration
504509
-- - token_response_expires_in value for the expires_in claim of the token response
505510
-- - token_response_contains_refresh_token whether to include a
506511
-- refresh token with the token response (a boolean in quotes, i.e. "true" or "false")

0 commit comments

Comments
 (0)