diff --git a/lib/json/jwk/set.rb b/lib/json/jwk/set.rb index 9a66160..bcac131 100644 --- a/lib/json/jwk/set.rb +++ b/lib/json/jwk/set.rb @@ -31,4 +31,4 @@ def as_json(options = {}) end end end -end \ No newline at end of file +end diff --git a/lib/json/jwk/set/fetcher.rb b/lib/json/jwk/set/fetcher.rb index 6d3d577..ce108fc 100644 --- a/lib/json/jwk/set/fetcher.rb +++ b/lib/json/jwk/set/fetcher.rb @@ -2,6 +2,8 @@ module JSON class JWK class Set module Fetcher + class MalformedJWKSet < JWT::Exception; end + class Cache def fetch(cache_key, options = {}) yield @@ -65,13 +67,15 @@ def self.fetch(jwks_uri, kid:, auto_detect: true, **options) kid ].collect(&:to_s).join(':') - jwks = Set.new( - JSON.parse( - cache.fetch(cache_key, options) do - http_client.get(jwks_uri).body - end - ) + parsed_jwks = JSON.parse( + cache.fetch(cache_key, options) do + http_client.get(jwks_uri).body + end ) + + raise MalformedJWKSet, "Malformed JWK Set: #{parsed_jwks.inspect}" unless parsed_jwks.is_a?(Hash) && parsed_jwks['keys'].is_a?(Array) + + jwks = Set.new(parsed_jwks) cache.delete(cache_key, options) if jwks[kid].blank? if auto_detect @@ -83,4 +87,4 @@ def self.fetch(jwks_uri, kid:, auto_detect: true, **options) end end end -end \ No newline at end of file +end diff --git a/spec/json/jwk/set/fetcher_spec.rb b/spec/json/jwk/set/fetcher_spec.rb index 5d14783..9971c77 100644 --- a/spec/json/jwk/set/fetcher_spec.rb +++ b/spec/json/jwk/set/fetcher_spec.rb @@ -4,7 +4,7 @@ describe JSON::JWK::Set::Fetcher::Cache do let(:something) { SecureRandom.hex(32) } - it 'just execute givne block' do + it 'just execute given block' do expect( subject.fetch('cache_key') do something @@ -111,6 +111,17 @@ def delete(cache_key) end.to request_to jwks_uri end + context "when the JWKS uri returns a structure that's not a valid JWK Set" do + it "raises a JSON::JWK::Set::Fetcher::MalformedJWKSet error" do + stub_request(:get, jwks_uri).to_return( + status: 200, + body: '"hello there"' # Note that this is valid JSON, but not a valid JWK Set + ) + + expect { subject }.to raise_error(JSON::JWK::Set::Fetcher::MalformedJWKSet) + end + end + context 'when unknown' do let(:kid) { 'unknown' } let(:cache_key) do