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

Add a JWKS implementation #525

Merged
merged 7 commits into from
Oct 21, 2022
Merged

Add a JWKS implementation #525

merged 7 commits into from
Oct 21, 2022

Conversation

bellebaum
Copy link
Contributor

This PR Draft implements JWK Sets (Part of RFC 7517) for easier handling of sets.

The goal was to make the handling of JWKS easier. E.g.

json = Net::HTTP.get(my_friends_jwks_uri)
jwks = JWT::JWK::Set.new(JSON.parse(json))
jwks.filter! { |key| key[:use] == 'sig' } # Signing Keys only
algorithms = jwks.map { |key| key[:alg] } # & algs_allowed_by_local_policy
JWT.decode some_token, nil, true, algorithms: algorithms, jwks: jwks

my_jwks = JWT::JWK::Set.new # Empty JWKS
my_jwks << JWT::JWK.new(OpenSSL::PKey::RSA.new(2048), use: 'sig')
my_jwks << OpenSSL::PKey::RSA.new(2048)
my_jwks.merge(jwks)
hash = my_jwks.export

The draft allows for basic manipulation of the set:

  • adding JWKs
  • merging JWKSs
  • filtering JWKs inside a JWKS
  • exporting to Hash

Where possible, I tried to use function names and semantics common in the standard library, to not subvert user expectations.

There are currently no tests or documentation, but I would like to get some early feedback to incorporate :)
The selection of methods on JWKSs is currently based on stuff I find helpful in my projects, so feel free to request any changes.

lib/jwt/jwk/key_finder.rb Show resolved Hide resolved
lib/jwt/jwk/set.rb Outdated Show resolved Hide resolved
@anakinj
Copy link
Member

anakinj commented Oct 18, 2022

This is a great idea. Left a few random comments

@bellebaum
Copy link
Contributor Author

The uniq! bug seems strange.
It sometimes works for me using the openssl gemfile, and I was hoping that this was some setup-issue, but apparently it is not.
The documentation seems to indicate that uniq! on Arrays filters duplicates as indicated by comparison using .eql?. Comparing the two elements manually using this method shows that they are indeed equal, yet uniq! does not find any duplicates. I think I am missing something obvious here.

@anakinj
Copy link
Member

anakinj commented Oct 19, 2022

About the #uniq! issue. I think the objects needs to have the #hash method. I think the documentation is wrong.

For example

def hash
  self[:kid].hash
end

@bellebaum bellebaum marked this pull request as ready for review October 20, 2022 10:48
@anakinj
Copy link
Member

anakinj commented Oct 20, 2022

The failing test is probably because ruby/openssl#538 has been shipped. Need to make the tests somehow pass on all versions. I'll take a look at this at some point in the near future, on a quick glimpse it looks great.

@anakinj
Copy link
Member

anakinj commented Oct 21, 2022

@bellebaum I fixed the CI for ruby-head could you be so kind and rebase/merge main into your branch?

Also a changelog entry would be great in regards to this feature addition.

@anakinj anakinj merged commit 771630d into jwt:main Oct 21, 2022
@anakinj
Copy link
Member

anakinj commented Oct 21, 2022

Great stuff. Big thank you for putting effort into this!

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.

None yet

2 participants