From 39bf909c21489fddd6fc25f71290923356b764a7 Mon Sep 17 00:00:00 2001 From: uowis Date: Thu, 9 May 2024 16:04:04 +0200 Subject: [PATCH] Implement forcing mfa from OIDC IDP --- app/server/lib/OIDCConfig.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/server/lib/OIDCConfig.ts b/app/server/lib/OIDCConfig.ts index 86f78bce..999aa5fd 100644 --- a/app/server/lib/OIDCConfig.ts +++ b/app/server/lib/OIDCConfig.ts @@ -69,6 +69,7 @@ export class OIDCConfig { private _endSessionEndpoint: string; private _skipEndSessionEndpoint: boolean; private _ignoreEmailVerified: boolean; + private _forceMfa: boolean; public constructor() { } @@ -113,6 +114,11 @@ export class OIDCConfig { defaultValue: false, })!; + this._forceMfa = section.flag('forceMfa').readBool({ + envVar: 'GRIST_OIDC_SP_FORCE_MFA', + defaultValue: false, + })!; + const issuer = await Issuer.discover(issuerUrl); this._redirectUrl = new URL(CALLBACK_URL, spHost).href; this._client = new issuer.Client({ @@ -159,6 +165,15 @@ export class OIDCConfig { throw new Error(`OIDCConfig: email not verified for ${userInfo.email}`); } + const amr = tokenSet.claims().amr; + if (this._forceMfa && (!amr || !amr.includes("mfa"))) { + if (!amr) { + throw new Error('OIDCConfig: could not verify mfa status due to missing amr claim. Make sure your IDP returns it.'); + } else if (!amr.includes("mfa")) { + throw new Error(`OIDCConfig: multi-factor-authentication is not enabled for ${userInfo.email}.`); + } + } + const profile = this._makeUserProfileFromUserInfo(userInfo); log.info(`OIDCConfig: got OIDC response for ${profile.email} (${profile.name}) redirecting to ${targetUrl}`);