Class: OmniauthOpenidFederation::Jwks::Cache

Inherits:
Object
  • Object
show all
Defined in:
lib/omniauth_openid_federation/jwks/cache.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(jwks_source, timeout_sec = 300) ⇒ Cache

Initialize JWKS cache

Parameters:

  • jwks_source (Object)

    The JWKS source (must respond to #jwks and optionally #reload!)

  • timeout_sec (Integer) (defaults to: 300)

    Minimum seconds between cache invalidations (default: 300 = 5 minutes)



26
27
28
29
30
31
# File 'lib/omniauth_openid_federation/jwks/cache.rb', line 26

def initialize(jwks_source, timeout_sec = 300)
  @jwks_source = jwks_source
  @timeout_sec = timeout_sec
  @cache_last_update = 0
  @cached_keys = nil
end

Instance Attribute Details

#cache_last_updateObject (readonly)

Returns the value of attribute cache_last_update.



20
21
22
# File 'lib/omniauth_openid_federation/jwks/cache.rb', line 20

def cache_last_update
  @cache_last_update
end

#jwks_sourceObject (readonly)

Returns the value of attribute jwks_source.



20
21
22
# File 'lib/omniauth_openid_federation/jwks/cache.rb', line 20

def jwks_source
  @jwks_source
end

#timeout_secObject (readonly)

Returns the value of attribute timeout_sec.



20
21
22
# File 'lib/omniauth_openid_federation/jwks/cache.rb', line 20

def timeout_sec
  @timeout_sec
end

Instance Method Details

#call(options = {}) ⇒ Array<Hash>

Get JWKS with automatic cache invalidation on kid_not_found

Parameters:

  • options (Hash) (defaults to: {})

    Options hash

Options Hash (options):

  • :kid_not_found (Boolean)

    Whether kid was not found (triggers invalidation if timeout passed)

  • :kid (String)

    The key ID that was not found

Returns:

  • (Array<Hash>)

    Array of signing keys (filtered from JWKS)



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/omniauth_openid_federation/jwks/cache.rb', line 39

def call(options = {})
  # Check if we should invalidate cache due to kid_not_found
  if options[:kid_not_found] && @cache_last_update < Time.now.to_i - @timeout_sec
    kid = options[:kid]
    OmniauthOpenidFederation::Logger.info("[Jwks::Cache] Invalidating JWK cache. Kid '#{kid}' not found from previous cache")
    @cached_keys = nil
    @jwks_source.reload! if @jwks_source.respond_to?(:reload!)
  end

  # Return cached keys or fetch fresh
  @cached_keys ||= begin
    @cache_last_update = Time.now.to_i
    jwks = @jwks_source.jwks

    # Ensure jwks is in the expected format
    keys = if jwks.is_a?(Hash) && (jwks.key?("keys") || jwks.key?(:keys))
      jwks["keys"] || jwks[:keys] || []
    elsif jwks.is_a?(Array)
      jwks
    else
      []
    end

    # Filter to signing keys only (for JWT verification)
    keys.select { |key| (key[:use] || key["use"]) == "sig" }
  end
end

#clear!void

This method returns an undefined value.

Clear the cache



70
71
72
73
# File 'lib/omniauth_openid_federation/jwks/cache.rb', line 70

def clear!
  @cached_keys = nil
  @cache_last_update = 0
end