Module: Doorkeeper::OAuth::ClientAuthentication::PrivateKeyJwt::KeyResolver

Defined in:
lib/doorkeeper/oauth/client_authentication/private_key_jwt/key_resolver.rb

Overview

Resolves the JWK Set a client's assertion must verify against: the jwks / jwks_uri attributes of its application, when the application model provides them (Doorkeeper defines no such columns itself).

Symmetric ("oct") keys are dropped: a symmetric key in a JWK Set is a shared secret, which this method must never verify against.

The jwt gem is always referenced as ::JWT: doorkeeper-jwt defines Doorkeeper::JWT, which would otherwise shadow the gem everywhere inside this module.

Class Method Summary collapse

Class Method Details

.jwk_set_for(application) ⇒ Object

A published JWK Set is remote, client-controlled input, so each level is type-checked before it is indexed into: a JWK Set that is not an object of objects must fail authentication, never raise out of the token endpoint.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/doorkeeper/oauth/client_authentication/private_key_jwt/key_resolver.rb', line 26

def self.jwk_set_for(application)
  raw = raw_jwks(application)
  return unless raw.is_a?(Hash)

  keys = raw["keys"] || raw[:keys]
  return unless keys.is_a?(Array)

  asymmetric = keys.grep(Hash).reject { |key| (key["kty"] || key[:kty]).to_s == "oct" }
  return if asymmetric.empty?

  ::JWT::JWK::Set.new({ "keys" => asymmetric })
rescue ::JWT::DecodeError, OpenSSL::OpenSSLError
  # A hostile key can fail to parse in more ways than JWT::JWKError:
  # a member that is not valid base64url raises JWT::Base64DecodeError
  # (a sibling of JWT::JWKError under JWT::DecodeError, not a
  # subclass), and an EC point that is not on its curve raises a bare
  # OpenSSL error. None of them may escape into the token endpoint.
  nil
end

.jwks_cacheObject

The built-in cache is process-local with a fixed TTL; the private_key_jwt_jwks_cache config option replaces it with any object answering fetch(url) { ... }.



92
93
94
# File 'lib/doorkeeper/oauth/client_authentication/private_key_jwt/key_resolver.rb', line 92

def self.jwks_cache
  Doorkeeper.config.private_key_jwt_jwks_cache || default_jwks_cache
end