OIDC: Add option to require group from IdP

This commit is contained in:
Lennart
2025-04-16 17:16:29 +02:00
parent ed84fb894f
commit fc147c388a
2 changed files with 22 additions and 1 deletions

View File

@@ -6,6 +6,7 @@ fn default_true() -> bool {
} }
#[derive(Deserialize, Serialize, Clone)] #[derive(Deserialize, Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct OidcConfig { pub struct OidcConfig {
pub name: String, pub name: String,
pub issuer: IssuerUrl, pub issuer: IssuerUrl,
@@ -13,6 +14,7 @@ pub struct OidcConfig {
pub client_secret: Option<ClientSecret>, pub client_secret: Option<ClientSecret>,
pub scopes: Vec<Scope>, pub scopes: Vec<Scope>,
pub allow_sign_up: bool, pub allow_sign_up: bool,
pub require_group: Option<String>,
} }
#[derive(Deserialize, Serialize, Clone)] #[derive(Deserialize, Serialize, Clone)]

View File

@@ -32,6 +32,14 @@ struct OidcState {
redirect_uri: Option<String>, redirect_uri: Option<String>,
} }
#[derive(Debug, Deserialize, Serialize)]
struct GroupAdditionalClaims {
#[serde(default)]
pub groups: Vec<String>,
}
impl openidconnect::AdditionalClaims for GroupAdditionalClaims {}
fn get_http_client() -> reqwest::Client { fn get_http_client() -> reqwest::Client {
reqwest::ClientBuilder::new() reqwest::ClientBuilder::new()
// Following redirects opens the client up to SSRF vulnerabilities. // Following redirects opens the client up to SSRF vulnerabilities.
@@ -166,7 +174,7 @@ pub async fn route_get_oidc_callback<AP: AuthenticationProvider>(
.ok_or(OidcError::Other("OIDC provider did not return an ID token"))? .ok_or(OidcError::Other("OIDC provider did not return an ID token"))?
.claims(&oidc_client.id_token_verifier(), &oidc_state.nonce)?; .claims(&oidc_client.id_token_verifier(), &oidc_state.nonce)?;
let user_info_claims: UserInfoClaims<EmptyAdditionalClaims, CoreGenderClaim> = oidc_client let user_info_claims: UserInfoClaims<GroupAdditionalClaims, CoreGenderClaim> = oidc_client
.user_info( .user_info(
token_response.access_token().clone(), token_response.access_token().clone(),
Some(id_claims.subject().clone()), Some(id_claims.subject().clone()),
@@ -175,6 +183,17 @@ pub async fn route_get_oidc_callback<AP: AuthenticationProvider>(
.await .await
.map_err(|_| OidcError::Other("Error fetching user info"))?; .map_err(|_| OidcError::Other("Error fetching user info"))?;
if let Some(require_group) = oidc_config.require_group {
if !user_info_claims
.additional_claims()
.groups
.contains(&require_group)
{
return Ok(HttpResponse::build(StatusCode::UNAUTHORIZED)
.body("User is not in an authorized group to use RustiCal"));
}
}
let user_id = user_info_claims let user_id = user_info_claims
.preferred_username() .preferred_username()
.ok_or(OidcError::Other("Missing preferred_username claim"))? .ok_or(OidcError::Other("Missing preferred_username claim"))?