Browse Source

Add support for SSO AMR claims

Signed-off-by: Kowalski Dragon (kowalski7cc) <kowalski7cc@users.noreply.github.com>
pull/7749/head
Kowalski Dragon (kowalski7cc) 2 weeks ago
parent
commit
1776d8c30c
No known key found for this signature in database GPG Key ID: C4E819BD2BC6233E
  1. 2
      .env.template
  2. 9
      src/api/identity.rs
  3. 1
      src/db/models/sso_auth.rs
  4. 3
      src/sso.rs

2
.env.template

@ -552,7 +552,7 @@
## Optional Master password policy (minComplexity=[0-4]), `enforceOnLogin` is not supported at the moment. ## Optional Master password policy (minComplexity=[0-4]), `enforceOnLogin` is not supported at the moment.
# SSO_MASTER_PASSWORD_POLICY='{"enforceOnLogin":false,"minComplexity":3,"minLength":12,"requireLower":false,"requireNumbers":false,"requireSpecial":false,"requireUpper":false}' # SSO_MASTER_PASSWORD_POLICY='{"enforceOnLogin":false,"minComplexity":3,"minLength":12,"requireLower":false,"requireNumbers":false,"requireSpecial":false,"requireUpper":false}'
## Skip Vaultwarden 2FA for SSO: false (never), true (always), auto (only when the IdP returns ACR level 2) ## Skip Vaultwarden 2FA for SSO: false (never), true (always), auto (only when the IdP returns an MFA ACR/AMR claim)
# SSO_SKIP_2FA=false # SSO_SKIP_2FA=false
## Use sso only for authentication not the session lifecycle ## Use sso only for authentication not the session lifecycle

9
src/api/identity.rs

@ -355,7 +355,14 @@ async fn sso_login(
let skip_2fa = match CONFIG.sso_skip_2fa().as_str() { let skip_2fa = match CONFIG.sso_skip_2fa().as_str() {
"true" => true, "true" => true,
"auto" => user_infos.acr.as_deref() == Some(SSO_2FA_ACR), "auto" => {
user_infos.acr.as_deref() == Some(SSO_2FA_ACR)
|| user_infos.amr.as_ref().is_some_and(|amr| {
amr.iter().any(|method| {
matches!(method.as_str(), "mfa" | "otp" | "fido2" | "webauthn" | "hwk")
})
})
}
_ => false, _ => false,
}; };
let twofactor_token = if skip_2fa { let twofactor_token = if skip_2fa {

1
src/db/models/sso_auth.rs

@ -36,6 +36,7 @@ pub struct OIDCAuthenticatedUser {
pub email_verified: Option<bool>, pub email_verified: Option<bool>,
pub user_name: Option<String>, pub user_name: Option<String>,
pub acr: Option<String>, pub acr: Option<String>,
pub amr: Option<Vec<String>>,
} }
impl_FromToSqlText!(OIDCAuthenticatedUser); impl_FromToSqlText!(OIDCAuthenticatedUser);

3
src/sso.rs

@ -308,6 +308,9 @@ pub async fn exchange_code(
email_verified, email_verified,
user_name: user_name.clone(), user_name: user_name.clone(),
acr: id_claims.auth_context_ref().map(|acr| acr.as_str().to_string()), acr: id_claims.auth_context_ref().map(|acr| acr.as_str().to_string()),
amr: id_claims
.auth_method_refs()
.map(|amr| amr.iter().map(|method| method.as_str().to_string()).collect()),
}; };
debug!("Authenticated user {authenticated_user:?}"); debug!("Authenticated user {authenticated_user:?}");

Loading…
Cancel
Save