Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OIDC] support JWK discovery through OIDC Discovery process #850

Merged
merged 9 commits into from
Aug 28, 2018
Merged

Conversation

mikz
Copy link
Contributor

@mikz mikz commented Aug 23, 2018

Load all JWK serialized keys offered by the OIDC Discovery endpoint.
Only RSA is supported at the moment.

This is internal change - how we load signing keys from the IDP. Previously we used Keycloak/RHSSO specific method: loading "public_key" from the issuer endpoint. That is not compatible with OIDC spec, so this PR introduces loading JWK keys from the "jwks_uri" offered by the OIDC Discovery.

It uses OpenSSL via FFI, so there can be some potential memory access issues leading to segfaults/memory leaks. However, I run out unit test suite 10000 times just to verify it does not crash and the memory usage does not increase.

This also unifies how we load OIDC configuration and improves its internal format. OIDC configuration is loaded even when using JSON configuration file (fixes #654), but only when not already provided.
JSON configurations with "oidc" configuration are no longer valid, as the internal structure changed.

TODO

  • stress test the JWK conversion for memory leaks / segfaults
  • unit test the OIDC discovery process
  • cleanup the OIDC configuration object
  • unify loading the OIDC configuration

@mikz mikz requested a review from a team as a code owner August 23, 2018 08:00
@mikz mikz changed the title [OIDC] support JWK discovery through OIDC Discovery process [WIP][OIDC] support JWK discovery through OIDC Discovery process Aug 23, 2018
@davidor davidor added this to the 3.3 milestone Aug 23, 2018
@mikz mikz force-pushed the oidc-jwk branch 3 times, most recently from 0dfafc4 to 46eb8f4 Compare August 23, 2018 15:09
formatted_key = formatted_key..string.sub(key, i, i+63).."\n"
end
formatted_key = formatted_key.."-----END PUBLIC KEY-----"
return formatted_key

This comment was marked as resolved.

if not res then return end
local keys = tab_new(0, #res.keys)

for i,jwk in ipairs(res.keys) do
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused loop variable 'i'

.respond_with{
status = 200,
headers = { content_type = 'application/json' },
body = fixture('oidc', 'jwk', 'forgerock.json')

This comment was marked as resolved.


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

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

This comment was marked as resolved.

@mikz mikz force-pushed the oidc-jwk branch 4 times, most recently from fd95997 to 21bfa66 Compare August 24, 2018 08:37
@mikz mikz changed the title [WIP][OIDC] support JWK discovery through OIDC Discovery process [OIDC] support JWK discovery through OIDC Discovery process Aug 24, 2018
@mikz
Copy link
Contributor Author

mikz commented Aug 27, 2018

@3scale/product this implements JWK originally planned for 3.4 release. Would be good to know to which JIRA to link it in the Changelog.

end)

describe(':openid_configuration(endpoint)', function()
it('loads configuration from the discovery endpoint', function()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also test the error cases

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

} }, keys)
end)

it('can process ForgeRock response', function()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is Forgerock different somehow or just an example?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has some keys with ciphers we don't support and possibly some properties can be different.

I wanted to keep it "ForgeRock" so it is obvious we support ForgeRock and it was copied from ForgeRock.

Over time we can add tests for edge cases and describe them like "does not crash on unknown ciphers". But for now I wanted to say this is ForgeRock and it works.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

return config
end

function _M:jwks(configuration)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a comment to make it clear that apart from extracting keys this method converts them to the PEM format?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@mikz mikz force-pushed the oidc-jwk branch 2 times, most recently from 48bbee2 to a37ba95 Compare August 28, 2018 08:20
@mikz mikz requested review from davidor and a team August 28, 2018 08:55
before_each(function() test_backend = test_backend_client.new() end)
before_each(function() loader.discovery.http_client.backend = test_backend end)

it('ignores config', function()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignores empty config?

Copy link
Contributor Author

@mikz mikz Aug 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. Will fix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

mikz added 4 commits August 28, 2018 13:57
Uses OpenSSL via FFI to convert JWK to PEM formatted certificate.
Currently only supports RSA.
Load configuration via OIDC Discovery endpoint.
This loader can be used to decorate existing loaders to add OIDC
information.
* Use JWK instead of "public_key" property
* All configuration loaders get OIDC configuration (including config
file, fixes #654)
Copy link
Contributor

@davidor davidor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎖️ 🏅

@mikz mikz merged commit 3e0bbba into master Aug 28, 2018
@mikz mikz deleted the oidc-jwk branch August 28, 2018 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

"oidc" configuration is not initialized when using THREESCALE_CONFIG_FILE
2 participants