Sto sviluppando una SPA con il back-end REST e voglio avere una semplice autenticazione basata su token. L'obiettivo di REST è di essere apolidi. Spiegherò il modello di sicurezza e cercherò di fare riferimento a tutte le fonti per le decisioni prese durante la progettazione. Vorresti un commento sull'intero setup e rispondi ad alcune domande specifiche.
Riepilogo
L'autenticazione verrà eseguita su un endpoint dedicato (ad esempio / auth / login). Le informazioni di accesso verranno passate come oggetto JSON. Le informazioni conterranno nome utente e password. All'accesso riuscito, verrà emesso un token JWT firmato. Questo token verrà utilizzato per l'accesso successivo all'API REST.
L'applicazione utilizzerà HTTPS e io controllo tutti i sottodomini.
Specifiche
JWT
- Contiene nome utente, emesso e scadenza
- Contiene indicazioni sull'appartenenza al ruolo all'interno di un'applicazione
- Contiene un token CSRF (generato casualmente da un generatore pseudocasuale crittograficamente sicuro)
- Firmato con una chiave HMAC (SHA256) disponibile solo per il server
Scadenza
Un token verrà emesso con una breve scadenza (ad esempio 30 minuti). Un token aggiornato con nuova scadenza verrà emesso ad ogni richiesta (scadenza della finestra scorrevole) con un termine ragionevole (ad esempio 8 ore). Il flusso del processo sarà il seguente:
- La richiesta di accesso iniziale emetterà un token con scadenza di 30 minuti
-
La prossima richiesta controllerà se il token è scaduto. Se è scaduto, l'accesso sarà bloccato. In caso contrario, una richiesta verrà soddisfatta. A quel punto verrà effettuato un controllo sull'età del token.
- Se l'età è entro la scadenza (meno di 8 ore), verrà generato un token aggiornato contenente un nuovo tempo di scadenza per altri 30 minuti. Rilasciato al momento rimarrà lo stesso del token originale.
- Se l'età del token è scaduta, non verranno generati token aggiornati e l'utente dovrà accedere di nuovo.
Razionale: voglio proteggere un token con una breve scadenza se è compromesso. Inoltre, non voglio forzare l'utente a relogin spesso. Un utente malintenzionato dovrebbe richiedere un nuovo token in un lasso di tempo inferiore alla scadenza di un token. Nel caso in cui un utente malintenzionato riesca a farlo, il tempo massimo che può utilizzare per il token è definito dalla scadenza. L'utente è in grado di rimanere online per un periodo di scadenza prefissato. Per una domanda di lavoro è sufficiente una scadenza di 8 ore o un giorno. Questa implementazione è abbastanza sicura? Quali sono i possibili inconvenienti e vulnerabilità?
trasporto e archiviazione JWT
JWT sarà trasportato come cookie httpOnly al client e verrà archiviato nel repository Cookies sul browser.
Razionale: proteggere un token dall'attacco XSS che comprometterebbe il token se tenuto all'interno di localStorage / sessionStorage. Questo è un consiglio da questo articolo. Qualcosa non va con questo approccio se non l'apertura dell'implementazione a un attacco CSRF?
Protezione CSRF
L'archiviazione dei token JWT all'interno dei cookie aprirà l'implementazione a un attacco CSRF. Per mitigare questo problema, viene implementato un metodo di cookie double submit. Il token CSRF viene generato e incluso all'interno del token JWT. Questo token viene inoltre fornito all'applicazione client in un oggetto JSON di una risposta alla richiesta di accesso. L'applicazione memorizzerà CSRF in localStorage e lo invierà ad ogni richiesta all'interno di un'intestazione personalizzata.
Razionale: come da risposta a questa domanda di riferimento questo articolo , per un'efficace protezione CSRF è necessario legare crittograficamente il token CSRF con un cookie di identificazione / autenticazione di sessione. Se includo un token in una JWT, è considerato crittograficamente legato a una sessione di sicurezza?
Concettualmente, vedi qualcosa di sbagliato in questa implementazione?