Fetch the JWKS and update the cached keys.
(&self)
| 220 | |
| 221 | /// Fetch the JWKS and update the cached keys. |
| 222 | async fn refresh_keys(&self) -> Result<(), String> { |
| 223 | debug!(uri = %self.jwks_uri, "Refreshing JWKS keys"); |
| 224 | |
| 225 | let jwk_set: JwkSet = self |
| 226 | .http |
| 227 | .get(&self.jwks_uri) |
| 228 | .send() |
| 229 | .await |
| 230 | .map_err(|e| format!("JWKS fetch failed: {e}"))? |
| 231 | .json() |
| 232 | .await |
| 233 | .map_err(|e| format!("JWKS parse failed: {e}"))?; |
| 234 | |
| 235 | let mut new_keys = HashMap::new(); |
| 236 | for key in &jwk_set.keys { |
| 237 | if key.kty != "RSA" { |
| 238 | continue; |
| 239 | } |
| 240 | let Some(ref kid) = key.kid else { |
| 241 | continue; |
| 242 | }; |
| 243 | match DecodingKey::from_rsa_components(&key.n, &key.e) { |
| 244 | Ok(dk) => { |
| 245 | new_keys.insert(kid.clone(), dk); |
| 246 | } |
| 247 | Err(e) => { |
| 248 | warn!(kid = %kid, error = %e, "Failed to parse JWK"); |
| 249 | } |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | info!(count = new_keys.len(), "JWKS keys loaded"); |
| 254 | *self.keys.write().await = new_keys; |
| 255 | *self.last_refresh.write().await = Instant::now(); |
| 256 | Ok(()) |
| 257 | } |
| 258 | |
| 259 | /// Refresh keys if the TTL has elapsed. |
| 260 | /// |
no test coverage detected