Skip to content

Commit

Permalink
WebClient: enforce 2fa and password requirements also with OIDC
Browse files Browse the repository at this point in the history
password and 2fa can be used with other protocols

Signed-off-by: Nicola Murino <[email protected]>
  • Loading branch information
drakkan committed Oct 21, 2024
1 parent 7e7005f commit 8d697bc
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 17 deletions.
44 changes: 29 additions & 15 deletions internal/httpd/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion static/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
2 changes: 1 addition & 1 deletion static/locales/it/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down

0 comments on commit 8d697bc

Please sign in to comment.