Module: Legion::Crypt::JwksClient
- Extended by:
- Logging::Helper
- Defined in:
- lib/legion/crypt/jwks_client.rb
Constant Summary collapse
- CACHE_TTL =
3600
Class Method Summary collapse
- .clear_cache ⇒ Object
- .fetch_keys(jwks_url) ⇒ Object
- .find_key(jwks_url, kid) ⇒ Object
- .prefetch!(jwks_url) ⇒ Object
- .start_background_refresh!(jwks_url, interval: CACHE_TTL) ⇒ Object
- .stop_background_refresh! ⇒ Object
Class Method Details
.clear_cache ⇒ Object
87 88 89 90 91 92 |
# File 'lib/legion/crypt/jwks_client.rb', line 87 def clear_cache stop_background_refresh! @cache_mutex.synchronize { @cache = {} } @locks_mutex.synchronize { @locks = {} } log.info 'JWKS cache cleared' end |
.fetch_keys(jwks_url) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/legion/crypt/jwks_client.rb', line 24 def fetch_keys(jwks_url) with_url_lock(jwks_url) do log.debug "JWKS fetch: #{jwks_url}" response = http_get(jwks_url) jwks_data = parse_response(response) keys = parse_jwks(jwks_data) cache_write(jwks_url, keys) log.info "JWKS fetched url=#{jwks_url} keys=#{keys.size}" keys end rescue StandardError => e handle_exception(e, level: :warn, operation: 'crypt.jwks.fetch_keys', jwks_url: jwks_url) raise end |
.find_key(jwks_url, kid) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/legion/crypt/jwks_client.rb', line 40 def find_key(jwks_url, kid) cached = cache_read(jwks_url) if cached && !expired?(cached[:fetched_at]) key = cached[:keys][kid] if key log.debug "JWKS cache hit: kid=#{kid}" return key end log.debug "JWKS cache miss for kid=#{kid}; refreshing keys" end keys = fetch_keys(jwks_url) key = keys[kid] return key if key raise Legion::Crypt::JWT::InvalidTokenError, "signing key not found: #{kid}" end |
.prefetch!(jwks_url) ⇒ Object
60 61 62 63 64 65 66 67 |
# File 'lib/legion/crypt/jwks_client.rb', line 60 def prefetch!(jwks_url) Thread.new do fetch_keys(jwks_url) rescue StandardError => e handle_exception(e, level: :debug, operation: 'crypt.jwks.prefetch', jwks_url: jwks_url) if respond_to?(:handle_exception) log.debug "JWKS prefetch failed for #{jwks_url}: #{e.}" if respond_to?(:log) end end |
.start_background_refresh!(jwks_url, interval: CACHE_TTL) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/legion/crypt/jwks_client.rb', line 69 def start_background_refresh!(jwks_url, interval: CACHE_TTL) stop_background_refresh! @refresh_task = Concurrent::TimerTask.new(execution_interval: interval, run_now: false) do fetch_keys(jwks_url) rescue StandardError => e handle_exception(e, level: :debug, operation: 'crypt.jwks.background_refresh', jwks_url: jwks_url) if respond_to?(:handle_exception) log.debug "JWKS background refresh failed: #{e.}" if respond_to?(:log) end @refresh_task.execute log.info "JWKS background refresh started (interval=#{interval}s)" if respond_to?(:log) end |
.stop_background_refresh! ⇒ Object
82 83 84 85 |
# File 'lib/legion/crypt/jwks_client.rb', line 82 def stop_background_refresh! @refresh_task&.shutdown @refresh_task = nil end |