From 9584ab68916d23e72b7ffd21f8ac2e056249ff77 Mon Sep 17 00:00:00 2001 From: Tomasz Raganowicz <7759113+tomekit@users.noreply.github.com> Date: Sun, 17 Dec 2023 12:49:02 +0100 Subject: [PATCH] Add field which can be used to determine if 2FA is enabled. That way the JWT consumer (e.g. if JWT is passed to some other API which verifies its authenticity) can only enforce 2FA AAL levels once 2FA is enabled. This allows to enforce 2FA only when at least one factor is used making 2FA roll-out optional. --- internal/api/token.go | 10 ++++++++++ internal/hooks/auth_hooks.go | 1 + 2 files changed, 11 insertions(+) diff --git a/internal/api/token.go b/internal/api/token.go index 7d94af3445..b3baf0468f 100644 --- a/internal/api/token.go +++ b/internal/api/token.go @@ -309,6 +309,15 @@ func (a *API) generateAccessToken(r *http.Request, tx *storage.Connection, user issuedAt := time.Now().UTC() expiresAt := issuedAt.Add(time.Second * time.Duration(config.JWT.Exp)).Unix() + atLeastOneVerifiedFactor := false + for i := 0; i < len(user.Factors); i++ { + factor := user.Factors[i] + if factor.IsVerified() { + atLeastOneVerifiedFactor = true + break + } + } + claims := &hooks.AccessTokenClaims{ StandardClaims: jwt.StandardClaims{ Subject: user.ID.String(), @@ -324,6 +333,7 @@ func (a *API) generateAccessToken(r *http.Request, tx *storage.Connection, user Role: user.Role, SessionId: sid, AuthenticatorAssuranceLevel: aal.String(), + AtLeastOneVerifiedFactor: atLeastOneVerifiedFactor, AuthenticationMethodReference: amr, IsAnonymous: user.IsAnonymous, } diff --git a/internal/hooks/auth_hooks.go b/internal/hooks/auth_hooks.go index 7113344294..78be5c1653 100644 --- a/internal/hooks/auth_hooks.go +++ b/internal/hooks/auth_hooks.go @@ -104,6 +104,7 @@ type AccessTokenClaims struct { AppMetaData map[string]interface{} `json:"app_metadata"` UserMetaData map[string]interface{} `json:"user_metadata"` Role string `json:"role"` + AtLeastOneVerifiedFactor bool `json:"has_factor,omitempty"` AuthenticatorAssuranceLevel string `json:"aal,omitempty"` AuthenticationMethodReference []models.AMREntry `json:"amr,omitempty"` SessionId string `json:"session_id,omitempty"`