Bläddra i källkod

WebClient: enforce 2fa and password requirements also with OIDC

password and 2fa can be used with other protocols

Signed-off-by: Nicola Murino <[email protected]>
Nicola Murino 1 år sedan
förälder
incheckning
8d697bcc94
3 ändrade filer med 31 tillägg och 17 borttagningar
  1. 29 15
      internal/httpd/oidc.go
  2. 1 1
      static/locales/en/translation.json
  3. 1 1
      static/locales/it/translation.json

+ 29 - 15
internal/httpd/oidc.go

@@ -212,21 +212,24 @@ func newOIDCPendingAuth(audience tokenAudience) oidcPendingAuth {
 }
 
 type oidcToken struct {
-	AccessToken          string          `json:"access_token"`
-	TokenType            string          `json:"token_type,omitempty"`
-	RefreshToken         string          `json:"refresh_token,omitempty"`
-	ExpiresAt            int64           `json:"expires_at,omitempty"`
-	SessionID            string          `json:"session_id"`
-	IDToken              string          `json:"id_token"`
-	Nonce                string          `json:"nonce"`
-	Username             string          `json:"username"`
-	Permissions          []string        `json:"permissions"`
-	HideUserPageSections int             `json:"hide_user_page_sections,omitempty"`
-	TokenRole            string          `json:"token_role,omitempty"` // SFTPGo role name
-	Role                 any             `json:"role"`                 // oidc user role: SFTPGo user or admin
-	CustomFields         *map[string]any `json:"custom_fields,omitempty"`
-	Cookie               string          `json:"cookie"`
-	UsedAt               int64           `json:"used_at"`
+	AccessToken                string          `json:"access_token"`
+	TokenType                  string          `json:"token_type,omitempty"`
+	RefreshToken               string          `json:"refresh_token,omitempty"`
+	ExpiresAt                  int64           `json:"expires_at,omitempty"`
+	SessionID                  string          `json:"session_id"`
+	IDToken                    string          `json:"id_token"`
+	Nonce                      string          `json:"nonce"`
+	Username                   string          `json:"username"`
+	Permissions                []string        `json:"permissions"`
+	HideUserPageSections       int             `json:"hide_user_page_sections,omitempty"`
+	MustSetTwoFactorAuth       bool            `json:"must_set_2fa,omitempty"`
+	MustChangePassword         bool            `json:"must_change_password,omitempty"`
+	RequiredTwoFactorProtocols []string        `json:"required_two_factor_protocols,omitempty"`
+	TokenRole                  string          `json:"token_role,omitempty"` // SFTPGo role name
+	Role                       any             `json:"role"`                 // oidc user role: SFTPGo user or admin
+	CustomFields               *map[string]any `json:"custom_fields,omitempty"`
+	Cookie                     string          `json:"cookie"`
+	UsedAt                     int64           `json:"used_at"`
 }
 
 func (t *oidcToken) parseClaims(claims map[string]any, usernameField, roleField string, customFields []string,
@@ -399,6 +402,9 @@ func (t *oidcToken) refreshUser(r *http.Request) error {
 	}
 	t.Permissions = user.Filters.WebClient
 	t.TokenRole = user.Role
+	t.MustSetTwoFactorAuth = user.MustSetSecondFactor()
+	t.MustChangePassword = user.MustChangePassword()
+	t.RequiredTwoFactorProtocols = user.Filters.TwoFactorAuthProtocols
 	return nil
 }
 
@@ -470,6 +476,9 @@ func (t *oidcToken) getUser(r *http.Request) error {
 	dataprovider.UpdateLastLogin(user)
 	t.Permissions = user.Filters.WebClient
 	t.TokenRole = user.Role
+	t.MustSetTwoFactorAuth = user.MustSetSecondFactor()
+	t.MustChangePassword = user.MustChangePassword()
+	t.RequiredTwoFactorProtocols = user.Filters.TwoFactorAuthProtocols
 	return nil
 }
 
@@ -550,6 +559,11 @@ func (s *httpdServer) oidcTokenAuthenticator(audience tokenAudience) func(next h
 				Role:                 token.TokenRole,
 				HideUserPageSections: token.HideUserPageSections,
 			}
+			if audience == tokenAudienceWebClient {
+				jwtTokenClaims.MustSetTwoFactorAuth = token.MustSetTwoFactorAuth
+				jwtTokenClaims.MustChangePassword = token.MustChangePassword
+				jwtTokenClaims.RequiredTwoFactorProtocols = token.RequiredTwoFactorProtocols
+			}
 			_, tokenString, err := jwtTokenClaims.createToken(s.tokenAuth, audience, util.GetIPFromRemoteAddress(r.RemoteAddr))
 			if err != nil {
 				setFlashMessage(w, r, newFlashMessage("Unable to create cookie", util.I18nError500Message))

+ 1 - 1
static/locales/en/translation.json

@@ -427,7 +427,7 @@
         "save_err": "Failed to save two-factor authentication configuration",
         "auth_code_required": "The authentication code is required",
         "no_protocol": "Please select at least a protocol",
-        "required_protocols": "Unable to disable two-factor authentication. The security policy configured for your account requires two-factor authentication for the following protocols: {{val}}",
+        "required_protocols": "The security policy configured for your account requires two-factor authentication for the following protocols: {{val}}",
         "recovery_codes_generate": "Generate new recovery codes",
         "recovery_codes_view": "View recovery codes"
     },

+ 1 - 1
static/locales/it/translation.json

@@ -427,7 +427,7 @@
         "save_err": "Impossibile salvare la configurazione dell'autenticazione a due fattori",
         "auth_code_required": "Il codice di autenticazione è obbligatorio",
         "no_protocol": "Seleziona almeno un protocollo",
-        "required_protocols": "Impossibile disabilitare l'autenticazione a due fattori. La politica di sicurezza configurata per il tuo account richiede l'autenticazione a due fattori per i seguenti protocolli: {{val}}",
+        "required_protocols": "La politica di sicurezza configurata per il tuo account richiede l'autenticazione a due fattori per i seguenti protocolli: {{val}}",
         "recovery_codes_generate": "Genera nuovi codici di ripristino",
         "recovery_codes_view": "Visualizza codici di ripristino"
     },