Autenticazione¶
Metodi Supportati¶
| Metodo | Implementazione | Note |
|---|---|---|
| Email + Password | Passport Local + bcrypt | Standard, con MFA opzionale |
| Google OAuth2 | Passport Google Strategy | Solo se utente esiste già nel sistema |
| Microsoft OAuth2 | Passport Microsoft Strategy | Solo se utente esiste già nel sistema |
| Passkey (WebAuthn) | SimpleWebAuthn / FIDO2 | Autenticazione biometrica/hardware |
Login Email/Password¶
Flusso¶
- Client →
POST /api/auth/loginconemailepassword LocalStrategypassa le credenziali aAuthService.validateUser()- bcrypt confronta la password con l'hash salvato nel DB
- Se valido e MFA disabilitato → emette il JWT definitivo
- Se valido e MFA abilitato → emette un tempToken di breve durata → cliente va alla verifica MFA
Sicurezza Password¶
- Hash con
bcrypt.genSalt()+bcrypt.hash()— salt random ad ogni hashing PasswordValidatorapplica regole di complessità prima di accettare nuove passwordPasswordHistorymemorizza gli hash precedenti — previene il riuso- Il campo
passwordèselect: falsenell'entity — non viene mai caricato nelle query normali
OAuth Sociale (Google e Microsoft)¶
Accesso su invito, non aperto
Il login sociale non crea account automaticamente.
Se l'email non esiste nel sistema → redirect a /login?error=user_not_found.
L'accesso deve essere concesso esplicitamente dall'amministratore.
Flusso OAuth¶
- Client →
GET /api/auth/social-login/:provider?returnUrl=... - Backend salva
returnUrlin cookiehttpOnly, secure, sameSite=lax(5 minuti) - Redirect verso il provider OAuth (Google o Microsoft)
- Callback → verifica utente → se MFA richiesto: redirect con
tempToken, altrimenti conaccess_token
Autenticazione a Due Fattori (MFA)¶
Tre metodi disponibili, scelti dall'utente:
| Metodo | Identificatore | Come funziona |
|---|---|---|
| App Authenticator (TOTP) | otp |
QR Code → App (Google Authenticator, Authy) → codice 6 cifre |
| Email OTP | email |
Codice monouso inviato via email |
| Passkey / WebAuthn | webauthn |
Biometria o chiave hardware, nessun codice |
MFA obbligatorio per Tenant Admin
Il Tenant Admin ha MFA forzato — impostato automaticamente alla creazione del tenant.
Flusso MFA Post-Login¶
- Login email/password va a buon fine → sistema rileva MFA abilitato
- Emette un
tempTokendi breve durata - Frontend reindirizza alla pagina di verifica MFA
- Utente inserisce codice (o usa passkey)
- Se valido → emissione JWT definitivo
JWT e Sessione¶
- Durata token: 1 giorno
- Storage:
localStoragenel browser - Iniezione:
Authorization: Bearer <token>via Axios defaults
Validazione Fresh dal Database¶
Importante
La JwtStrategy non si fida solo del payload del token.
Ad ogni richiesta recupera l'utente fresco dal DB (findByIdWithSecrets).
Questo garantisce che:
- Cambi ai moduli assegnati prendono effetto immediatamente
- Account disabilitati vengono bloccati subito
- Non serve aspettare la scadenza del token per revocare l'accesso
Passkey / WebAuthn¶
Le passkey (FIDO2/WebAuthn) permettono autenticazione senza password tramite biometria o chiavi hardware. L'entity Authenticator memorizza le credenziali per ogni utente.
Endpoint:
GET /api/auth/passkey/register-options→ opzioni per registrazionePOST /api/auth/passkey/register-verify→ verifica e salva la passkeyGET /api/auth/passkey/login-options→ opzioni per autenticazionePOST /api/auth/passkey/login-verify→ verifica e emette token
Impersonation (Accesso come Utente)¶
Il Global Admin può accedere alla sessione di un utente con POST /api/auth/impersonate/:id, ma solo se l'utente ha attivato il flag isImpersonationConsentGranted.
Tracciabilità completa
Ogni impersonation viene sempre loggata nell'audit log. L'azione non può avvenire silenziosamente.
Protezioni Anti-Attacco¶
| Meccanismo | Implementazione |
|---|---|
| Anti-enumeration | forgotPassword ritorna sempre la stessa risposta generica |
| Alert login falliti | Ogni fallimento notifica gli admin + logga in AuditLog |
| Throttling | 1000 richieste/minuto globale (ThrottlerModule NestJS) |
| Campi sensibili nascosti | password, twoFactorSecret, tokens: select: false |
| Soft Delete utenti | DeleteDateColumn — dati preservati, non eliminati fisicamente |
| Cookie OAuth sicuri | httpOnly, secure, sameSite=lax, scadenza 5 minuti |