OIDC directory: Fetch name and group claims from userinfo endpoint when missing from the JWT token
This commit is contained in:
@@ -13,15 +13,17 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If
|
|||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
- DANE: Treat DNSSEC `bogus` as a temporary failures to prevent downgrade attacks.
|
- DANE: Treat DNSSEC `bogus` as a temporary failures to prevent downgrade attacks.
|
||||||
- OIDC:
|
- OIDC provider:
|
||||||
- `ECDSA` private key support for `SEC1` format.
|
- `ECDSA` private key support for `SEC1` format.
|
||||||
- Allow ports in `redirect_uri` for loopback addresses.
|
- Allow ports in `redirect_uri` for loopback addresses.
|
||||||
|
- OIDC directory:
|
||||||
|
- Removing a user from all groups does not sync the changes correctly.
|
||||||
|
- Fetch `name` and `group` claims from userinfo endpoint when missing from the JWT token.
|
||||||
- PostgreSQL: Include error chain in error messages.
|
- PostgreSQL: Include error chain in error messages.
|
||||||
- Prometheus: event counters are exported with incorrect metric names.
|
- Prometheus: event counters are exported with incorrect metric names.
|
||||||
- Registry: Changing the type of an existing account from `user` to `group` panics.
|
- Registry: Changing the type of an existing account from `user` to `group` panics.
|
||||||
- Masked emails: Return `UnknownRecipient` only for disabled or expired masked emails.
|
- Masked emails: Return `UnknownRecipient` only for disabled or expired masked emails.
|
||||||
- IDN: `sanitize_email` rejects valid Punycode domains.
|
- IDN: `sanitize_email` rejects valid Punycode domains.
|
||||||
- Directory: Removing a user from all groups does not sync the changes correctly.
|
|
||||||
- Auto-ban: IP block expiration ignores per-reason ban durations.
|
- Auto-ban: IP block expiration ignores per-reason ban durations.
|
||||||
|
|
||||||
## [0.16.11] - 2026-06-25
|
## [0.16.11] - 2026-06-25
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use jsonwebtoken::{
|
|||||||
jwk::{self, JwkSet},
|
jwk::{self, JwkSet},
|
||||||
};
|
};
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
|
use serde_json::Value;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
use trc::AuthEvent;
|
use trc::AuthEvent;
|
||||||
@@ -77,12 +78,38 @@ impl OpenIdDirectory {
|
|||||||
|
|
||||||
self.validate_scopes(&token_data.claims)?;
|
self.validate_scopes(&token_data.claims)?;
|
||||||
|
|
||||||
let (email, claims) = if let Ok(email) = self.resolve_email(&token_data.claims)
|
let mut claims = token_data.claims;
|
||||||
{
|
let jwt_email = self.resolve_email(&claims).ok();
|
||||||
(email, token_data.claims)
|
let missing_profile = self
|
||||||
} else {
|
.config
|
||||||
let claims = self.fetch_userinfo(token).await?;
|
.claim_name
|
||||||
(self.resolve_email(&claims)?, claims)
|
.as_ref()
|
||||||
|
.is_some_and(|claim| claims.get(claim).is_none())
|
||||||
|
|| self
|
||||||
|
.config
|
||||||
|
.claim_groups
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|claim| claims.get(claim).is_none());
|
||||||
|
|
||||||
|
if jwt_email.is_none() || missing_profile {
|
||||||
|
match self.fetch_userinfo(token).await {
|
||||||
|
Ok(userinfo) => {
|
||||||
|
if let (Some(base), Value::Object(extra)) =
|
||||||
|
(claims.as_object_mut(), userinfo)
|
||||||
|
{
|
||||||
|
for (key, value) in extra {
|
||||||
|
base.entry(key).or_insert_with(|| value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) if jwt_email.is_none() => return Err(err),
|
||||||
|
Err(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let email = match jwt_email {
|
||||||
|
Some(email) => email,
|
||||||
|
None => self.resolve_email(&claims)?,
|
||||||
};
|
};
|
||||||
return self.build_account(email, &claims);
|
return self.build_account(email, &claims);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user