@@ -5,57 +5,37 @@ module JWK
55 class KeyFinder
66 def initialize ( options )
77 jwks_or_loader = options [ :jwks ]
8- @jwks = jwks_or_loader if jwks_or_loader . is_a? ( Hash )
9- @jwk_loader = jwks_or_loader if jwks_or_loader . respond_to? ( :call )
8+
9+ @jwks_loader = if jwks_or_loader . respond_to? ( :call )
10+ jwks_or_loader
11+ else
12+ -> ( _options ) { jwks_or_loader }
13+ end
1014 end
1115
1216 def key_for ( kid )
1317 raise ::JWT ::DecodeError , 'No key id (kid) found from token headers' unless kid
1418
1519 jwk = resolve_key ( kid )
1620
17- raise ::JWT ::DecodeError , 'No keys found in jwks' if jwks_keys . empty ?
21+ raise ::JWT ::DecodeError , 'No keys found in jwks' unless @jwks . any ?
1822 raise ::JWT ::DecodeError , "Could not find public key for kid #{ kid } " unless jwk
1923
20- :: JWT :: JWK . import ( jwk ) . keypair
24+ jwk . keypair
2125 end
2226
2327 private
2428
2529 def resolve_key ( kid )
26- jwk = find_key ( kid )
30+ # First try without invalidation to facilitate application caching
31+ @jwks ||= JWT ::JWK ::Set . new ( @jwks_loader . call ( kid : kid ) )
32+ jwk = @jwks . find { |key | key [ :kid ] == kid }
2733
2834 return jwk if jwk
2935
30- if reloadable?
31- load_keys ( invalidate : true , kid_not_found : true , kid : kid ) # invalidate for backwards compatibility
32- return find_key ( kid )
33- end
34-
35- nil
36- end
37-
38- def jwks
39- return @jwks if @jwks
40-
41- load_keys
42- @jwks
43- end
44-
45- def load_keys ( opts = { } )
46- @jwks = @jwk_loader . call ( opts )
47- end
48-
49- def jwks_keys
50- Array ( jwks [ :keys ] || jwks [ 'keys' ] )
51- end
52-
53- def find_key ( kid )
54- jwks_keys . find { |key | ( key [ :kid ] || key [ 'kid' ] ) == kid }
55- end
56-
57- def reloadable?
58- @jwk_loader
36+ # Second try, invalidate for backwards compatibility
37+ @jwks = JWT ::JWK ::Set . new ( @jwks_loader . call ( invalidate : true , kid_not_found : true , kid : kid ) )
38+ @jwks . find { |key | key [ :kid ] == kid }
5939 end
6040 end
6141 end
0 commit comments