Ho una nuova SPA con un modello di autenticazione stateless che utilizza JWT. Mi viene spesso chiesto di fare riferimento a OAuth per i flussi di autenticazione come se mi chiedesse di inviare 'Bearer tokens' per ogni richiesta invece di una semplice intestazione di token ma penso che OAuth sia molto più complesso di una semplice autenticazione basata su JWT. Quali sono le principali differenze, dovrei far comportare l'autenticazione JWT come OAuth?
Sto anche usando il JWT come mio XSRF-TOKEN per prevenire XSRF ma mi viene chiesto di tenerli separati? Dovrei tenerli separati? Qualsiasi aiuto qui sarà apprezzato e potrebbe portare a una serie di linee guida per la comunità.
TL;DR Se hai scenari molto semplici, come una singola applicazione client, una singola API, allora potrebbe non pagare per andare OAuth 2.0, d'altra parte, un sacco di client diversi (browser-based, mobile nativo, lato server, ecc) allora attenersi alle regole OAuth 2.0 potrebbe rendere più gestibile che cercare di rollare il proprio sistema.
Come detto in un'altra risposta, JWT (Learn JSON Web Tokens) è solo un formato di token, definisce un meccanismo compatto e autonomo per trasmettere dati tra le parti in un modo che può essere verificato e fidato perché è firmato digitalmente. Inoltre, le regole di codifica di un JWT rendono questi token molto facili da usare nel contesto di HTTP.
Essendo autocontenuti (il token effettivo contiene informazioni su un dato soggetto) sono anche una buona scelta per implementare meccanismi di autenticazione stateless (aka Guarda mamma, niente sessioni!). Quando si segue questa strada e l'unica cosa che un soggetto deve presentare per ottenere l'accesso a una risorsa protetta è il token stesso, il token in questione può essere chiamato token portatore.
In pratica, quello che state facendo può già essere classificato come basato su token al portatore. Tuttavia, si consideri che non si stanno utilizzando token al portatore come specificato dalle specifiche relative a OAuth 2.0 (vedi RFC 6750). Ciò implicherebbe, basandosi sull'intestazione HTTP Authorization
e utilizzando lo schema di autenticazione Bearer
.
Per quanto riguarda l'uso del JWT per prevenire il CSRF senza conoscere i dettagli esatti, è difficile accertare la validità di tale pratica, ma ad essere onesti non sembra corretta e/o utile. Il seguente articolo (Cookies vs Tokens: The Definitive Guide) può essere una lettura utile su questo argomento, in particolare la sezione XSS and XSRF Protection.
Un ultimo consiglio, anche se non avete bisogno di andare completamente in OAuth 2.0, vi raccomanderei fortemente di passare il vostro token di accesso all'interno dell'intestazione Authorization
invece di andare con intestazioni personalizzate. Se sono davvero token al portatore segui le regole di RFC 6750, altrimenti puoi sempre creare uno schema di autenticazione personalizzato e usare comunque quell'intestazione.
Le intestazioni di autorizzazione sono riconosciute e trattate in modo speciale dai proxy e dai server HTTP. Quindi, l'uso di tali intestazioni per l'invio di token di accesso ai server di risorse riduce la probabilità di fuga o di memorizzazione involontaria delle richieste autenticate in generale, e specialmente delle intestazioni di autorizzazione.
(fonte: RFC 6819, sezione 5.4.1)
OAuth 2.0 definisce un protocollo, cioè specifica come vengono trasferiti i token, JWT definisce un formato di token.
OAuth 2.0 e "autenticazione JWT" hanno un aspetto simile quando si tratta della (2a) fase in cui il client presenta il token al Resource Server: il token viene passato in un header.
Ma "JWT authentication" non è uno standard e non specifica come il client ottiene il token in primo luogo (il 1° stadio). È da qui che deriva la complessità percepita di OAuth: definisce anche vari modi in cui il client può ottenere un token di accesso da qualcosa che si chiama Authorization Server.
Quindi la vera differenza è che JWT è solo un formato di token, OAuth 2.0 è un protocollo (che può usare un JWT come formato di token).
In primo luogo, dobbiamo differenziare JWT e OAuth. Fondamentalmente, JWT è un formato di token. OAuth è un protocollo di autorizzazione che può usare JWT come token. OAuth utilizza la memorizzazione lato server e lato client. Se vuoi fare un vero logout devi andare con OAuth2. L'autenticazione con token JWT non può logout in realtà. Perché non avete un server di autenticazione che tiene traccia dei token. Se volete fornire un'API a clienti di terze parti, dovete usare anche OAuth2. OAuth2 è molto flessibile. L'implementazione di JWT è molto facile e non richiede molto tempo. Se la vostra applicazione ha bisogno di questo tipo di flessibilità, dovreste andare con OAuth2. Ma se non avete bisogno di questo caso d'uso, implementare OAuth2 è una perdita di tempo.
Il token XSRF viene sempre inviato al client in ogni intestazione di risposta. Non importa se un token CSRF viene inviato in un token JWT o meno, perché il token CSRF è protetto con se stesso. Quindi inviare il token CSRF in JWT non è necessario.