Skip to content

Commit

Permalink
OIDC: Fix discovery content-type issues
Browse files Browse the repository at this point in the history
When JWK response was not application/json content_type, the keys cannot
be parsed and OIDC flow failed.

With this fix, if the application is returning `jwk-set+json`, something
valid that was not parsed as we should.[0]

[0] https://tools.ietf.org/html/rfc7517#section-8.5.1

Fix: THREESCALE-6913

Signed-off-by: Eloy Coto <[email protected]>
  • Loading branch information
eloycoto committed Apr 20, 2021
1 parent df409f9 commit 2690c13
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Fixed issues with URI when using Routing Policy [PR #1245](https://github.com/3scale/APIcast/pull/1245) [THREESCALE-6410](https://issues.redhat.com/browse/THREESCALE-6410)
- Fixed typo on TLS jsonschema [PR #1260](https://github.com/3scale/APIcast/pull/1260) [THREESCALE-6390](https://issues.redhat.com/browse/THREESCALE-6390)
- Fixed host header format on http_ng resty [PR #1264](https://github.com/3scale/APIcast/pull/1264) [THREESCALE-2235](https://issues.redhat.com/browse/THREESCALE-2235)
- Fixed issues on OIDC jwk discovery [PR #1268](https://github.com/3scale/APIcast/pull/1268) [THREESCALE-6913](https://issues.redhat.com/browse/THREESCALE-6913)


### Added
Expand Down
16 changes: 13 additions & 3 deletions gateway/src/resty/oidc/discovery.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ local oidc_log_level = ngx[string.upper(resty_env.value('APICAST_OIDC_LOG_LEVEL'

local cache_max_size = 100

local json_content_types = {
["application/json"] = true,
["application/jwk-set+json"] = true
}

local _M = {
_TYPE = "oidc_discovery"
}
Expand All @@ -32,7 +37,7 @@ local function mime_type(content_type)
end

local function decode_json(response)
if mime_type(response.headers.content_type) == 'application/json' then
if json_content_types[mime_type(response.headers.content_type)] then
return cjson.decode(response.body)
else
return nil, 'not json'
Expand Down Expand Up @@ -111,7 +116,7 @@ function _M:openid_configuration(issuer)

local config = decode_json(res)
if not config then
ngx.log(oidc_log_level, 'invalid OIDC Provider, expected application/json got: ', res.headers.content_type, ' body: ', res.body)
ngx.log(oidc_log_level, 'invalid OIDC Provider, cannot decode the message:: ', res.headers.content_type, ' body: ', res.body)
return nil, 'invalid JSON'
end
return config
Expand Down Expand Up @@ -140,7 +145,12 @@ function _M:jwks(configuration)
local res = http_client.get(jwks_uri)

if res.status == 200 then
return jwk.convert_keys(decode_json(res))
local val, err = jwk.convert_keys(decode_json(res))
if err then
ngx.log(oidc_log_level, 'invalid JWKS config, cannot decode the message: ', res.headers.content_type, ', error:', err ,', body: ', res.body)
return nil, "Cannot convert keys"
end
return val
else
return nil, 'invalid response'
end
Expand Down
31 changes: 30 additions & 1 deletion spec/resty/oidc/discovery_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,35 @@ UwIDAQAB
} }, keys)
end)

it('can process jwk-set+json content type ', function()
local config = { jwks_uri = 'https://idp.example.com/auth/realms/foo/jwks' }
test_backend
.expect{ url = config.jwks_uri }
.respond_with{
status = 200,
headers = { content_type = 'application/jwk-set+json;charset=UTF-8' },
body = fixture('oidc', 'jwk', 'forgerock.json')
}

local keys = assert(discovery:jwks(config))

assert.same(cjson.decode(fixture('oidc', 'jwk', 'forgerock.apicast.json')),
keys)
end)

it('cannot process text content type ', function()
local config = { jwks_uri = 'https://idp.example.com/auth/realms/foo/jwks' }
test_backend
.expect{ url = config.jwks_uri }
.respond_with{
status = 200,
headers = { content_type = 'application/text' },
body = fixture('oidc', 'jwk', 'forgerock.json')
}

assert.returns_error('Cannot convert keys', discovery:jwks(config))
end)

it('can process ForgeRock response', function()
local config = { jwks_uri = 'https://idp.example.com/auth/realms/foo/jwks' }
test_backend
Expand Down Expand Up @@ -180,7 +209,7 @@ UwIDAQAB
.expect{ url = config.jwks_uri }
.respond_with{ status = 200, body = '' }

assert.returns_error('not json', discovery:jwks(config))
assert.returns_error('Cannot convert keys', discovery:jwks(config))
end)
end)
end)

0 comments on commit 2690c13

Please sign in to comment.