feat: fetch keycloak jwks + cache

This commit is contained in:
2026-04-09 12:47:09 +02:00
commit 5eb8da88f8
8 changed files with 2296 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
use jsonwebtoken::{decode, decode_header, Algorithm, DecodingKey, Validation};
use serde::{Deserialize, Serialize};
static ISSUER: &str = "https://auth.iceberg.black/realms/iceberg";
#[derive(Debug, Deserialize, Serialize)]
pub struct Claims {
pub sub: String,
pub preferred_username: Option<String>,
pub exp: usize,
pub iss: String,
pub aud: Option<String>,
pub realm_access: Option<RealmAccess>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct RealmAccess {
pub roles: Vec<String>,
}
pub fn validate_token(token: &str, jwks: &serde_json::Value) -> Result<Claims, ()> {
let header = decode_header(token).map_err(|_| ())?;
let kid = header.kid.ok_or(())?;
let keys = jwks["keys"].as_array().ok_or(())?;
let key = keys
.iter()
.find(|k| k["kid"] == kid)
.ok_or(())?;
let n = key["n"].as_str().ok_or(())?;
let e = key["e"].as_str().ok_or(())?;
let decoding_key =
DecodingKey::from_rsa_components(n, e).map_err(|_| ())?;
let mut validation = Validation::new(Algorithm::RS256);
validation.set_issuer(&[ISSUER]);
let token_data =
decode::<Claims>(token, &decoding_key, &validation).map_err(|_| ())?;
Ok(token_data.claims)
}