Module: Legion::Crypt::JwksClient
Constant Summary
collapse
- CACHE_TTL =
3600
Logging::Helper::CompatLogger
Class Method Summary
collapse
handle_exception, log
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.message}" 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.message}" 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
|