Sicurezza API REST Token archiviato vs JWT vs OAuth


104

Sto ancora cercando di trovare la migliore soluzione di sicurezza per proteggere l'API REST, perché la quantità di applicazioni mobili e API aumenta ogni giorno.

Ho provato diversi modi di autenticazione, ma ho ancora dei malintesi, quindi ho bisogno del consiglio di qualcuno più esperto.

Lasciami dire, come capisco tutte queste cose. Se capisco qualcosa in modo errato, per favore fatemi sapere.

Per quanto l'API REST sia apolide e WEB in generale, è necessario inviare alcuni dati di autenticazione in ciascuna richiesta (cookie, token ....). Conosco tre meccanismi ampiamente utilizzati per autenticare l'utente

  1. Token con HTTPS. Ho usato questo approccio molte volte, è abbastanza buono con HTTPS. Se l'utente fornisce la password e l'accesso corretti, riceverà il token in risposta e lo utilizzerà per le ulteriori richieste. Il token viene generato dal server e memorizzato, ad esempio nella tabella separata o lo stesso in cui sono archiviate le informazioni dell'utente. Pertanto, per ogni server di richieste controlla se l'utente ha un token ed è lo stesso del database. Tutto è abbastanza semplice.

  2. Token JWT. Questo token è auto-descrittivo, contiene tutte le informazioni necessarie sul token stesso, l'utente non può modificare, ad esempio, la data di scadenza o qualsiasi altro reclamo, poiché questo token è generato (firmato) dal server con una parola chiave segreta. Anche questo è chiaro. Ma un grosso problema, personalmente per me, come invalidare il token.

  3. OAuth 2. Non capisco perché questo approccio debba essere usato quando la comunicazione viene stabilita direttamente tra server e client. A quanto ho capito, il server OAuth viene utilizzato per emettere token con ambito limitato per consentire ad altre applicazioni di accedere alle informazioni dell'utente senza memorizzare password e login. Questa è un'ottima soluzione per i social network, quando l'utente desidera registrarsi su alcune pagine, il server può richiedere autorizzazioni per ottenere informazioni sugli utenti, ad esempio da Twitter o Facebook, e riempire i campi di registrazione con i dati degli utenti e così via.

Prendi in considerazione il client mobile per il negozio online.

Prima domanda dovrei preferire JWT rispetto al token di primo tipo? Per quanto riguarda l'utente di accesso / disconnessione sul client mobile, devo archiviare un token da qualche parte o in caso di JWT, il token deve essere invalidato al momento della disconnessione. Approcci diversi sono utilizzati per invalidare il token, uno dei è quello di creare un elenco di token non valido (lista nera). Hmm. La tabella / file avrà dimensioni molto maggiori rispetto a se il token fosse archiviato nella tabella e associato all'utente e appena rimosso al logout.

Quindi quali sono i vantaggi del token JWT?

Seconda domanda su OAuth, dovrei usarlo in caso di comunicazione diretta con il mio server? Qual è lo scopo di un ulteriore livello tra client e server solo per emettere token, ma la comunicazione non avverrà con il server oauth ma con il server principale. A quanto ho capito, il server OAuth è responsabile solo di concedere autorizzazioni (token) per app di terze parti per accedere alle informazioni private dell'utente. Ma la mia applicazione client mobile non è di terze parti.


Grazie, me lo stavo chiedendo di recente. Sono andato con la gestione delle sessioni (Becher), ed ho eliminato i token di sessione dopo un'ora. Oauth non sembrava la soluzione giusta.
JasTonAChair l'

Risposte:


86

Considera il primo caso. Ogni cliente ottiene un ID casuale che dura per la durata della sessione, che può essere di diversi giorni se lo desideri. Quindi si memorizzano le informazioni relative a quella sessione da qualche parte sul lato server. Potrebbe essere in un file o in un database. Supponiamo che tu passi l'ID tramite un cookie ma potresti usare l'URL o un'intestazione HTTP.

ID sessione / cookie

Professionisti:

  • Facile da programmare sia per client che per server.
  • Facile distruggere una sessione quando qualcuno si disconnette.

Contro:

  • Il lato server deve periodicamente eliminare le sessioni scadute in cui il client non si è disconnesso.
  • Ogni richiesta HTTP richiede una ricerca nell'archivio dati.
  • I requisiti di archiviazione aumentano man mano che un numero maggiore di utenti ha sessioni attive.
  • Se sono presenti più server HTTP front-end, i dati della sessione memorizzata devono essere accessibili da tutti. Questo potrebbe essere un po 'più di lavoro che archiviarlo su un server. I problemi maggiori sono l'archivio dati diventa un singolo punto di errore e può diventare un collo di bottiglia.

Token Web JSON (JWT)

Nel secondo caso i dati vengono archiviati in un JWT che viene passato invece che sul server.

Professionisti:

  • I problemi di archiviazione sul lato server sono spariti.
  • Il codice lato client è semplice.

Contro:

  • La dimensione JWT potrebbe essere maggiore di un ID sessione. Potrebbe influire sulle prestazioni della rete poiché è incluso in ogni richiesta HTTP.
  • I dati memorizzati nel JWT sono leggibili dal client. Questo potrebbe essere un problema.
  • Il lato server necessita di codice per generare, convalidare e leggere i JWT. Non è difficile ma c'è un po 'di una curva di apprendimento e la sicurezza dipende da questo.

    Chiunque ottenga una copia della chiave di firma può creare JWT. Potresti non sapere quando questo accade.

    C'era (c'è?) Un bug in alcune librerie che accettava qualsiasi JWT firmato con l'algoritmo "none" in modo che chiunque potesse creare JWT di cui il server si sarebbe fidato.

  • Per revocare un JWT prima che scada, è necessario utilizzare un elenco di revoche. Questo ti riporta ai problemi di archiviazione sul lato server che stavi cercando di evitare.

OAuth

Spesso OAuth viene utilizzato per l'autenticazione (ad es. Identità) ma può essere utilizzato per condividere altri dati come un elenco di contenuti che l'utente ha acquistato ed è autorizzato a scaricare. Può anche essere utilizzato per concedere l'accesso alla scrittura di dati archiviati da terze parti. È possibile utilizzare OAuth per autenticare gli utenti e quindi utilizzare l'archiviazione sul lato server o JWT per i dati della sessione.

Professionisti:

  • Nessun codice per gli utenti di iscriversi o reimpostare la password.
  • Nessun codice per inviare un'e-mail con un collegamento di convalida e quindi convalidare l'indirizzo.
  • Gli utenti non devono imparare / scrivere un altro nome utente e password.

Contro:

  • Dipendi dalla terza parte affinché gli utenti possano utilizzare il tuo servizio. Se il loro servizio si interrompe o lo interrompono, è necessario capire qualcos'altro. Ad esempio: come migrare i dati dell'account dell'utente se la loro identità cambia da "foo@a.com" a "bar@b.com"?
  • Di solito devi scrivere il codice per ciascun provider. ad es. Google, Facebook, Twitter.
  • Tu o i tuoi utenti potreste avere problemi di privacy. I provider sanno quali dei loro utenti utilizzano il tuo servizio.
  • Ti fidi del provider. È possibile che un provider rilasci token validi per un utente a qualcun altro. Questo potrebbe essere per scopi leciti o meno.

miscellaneo

  • Sia gli ID di sessione che i JWT possono essere copiati e utilizzati da più utenti. È possibile memorizzare l'indirizzo IP del client in un JWT e convalidarlo, ma ciò impedisce ai client di eseguire il roaming da Wi-Fi a cellulare.

Per aggiungere alla tua risposta, oAuth potrebbe non essere utile quando l'utente desidera registrarsi utilizzando i propri account aziendali che di solito non sono associati o collegati a nessuno dei siti Web di social network o google.
Aftab Naveed,

5
Non so perché questa è la risposta accettata? essa non risponde alla vera domanda, basta riformare la questione in altro modo
amd

1
Dici: "I dati memorizzati nel JWT sono leggibili dal client. Potrebbe trattarsi di un problema. Perché non utilizzare JWE se questo è un problema?
Silver,

Questa risposta confonde mele e arance. Non è necessario confrontarli con OAuth 2.0 (la specifica "autorizzazione"). Ciò che OP deve sapere è: "Flusso password proprietario risorsa" - che è l'autenticazione come una concessione.
Onur Yıldırım,

5

Chiediti perché è necessario invalidare il token originale.

Un utente accede, viene generato un token e l'app si spegne.

L'utente preme il logout, viene generato un nuovo token e sostituisce il token originale. Ancora una volta, va tutto bene.

Sembra che ti preoccupi del caso in cui entrambi i token sono in giro. Che cosa succede se l'utente si disconnette e quindi in qualche modo effettua una richiesta utilizzando il token di accesso. Quanto è realistico questo scenario? È solo un problema durante il logout o ci sono molti scenari possibili in cui più token possono essere un problema?

Io stesso non penso che valga la pena preoccuparsi. Se qualcuno intercetta e decodifica i tuoi dati https crittografati, allora hai problemi molto più grandi.

Puoi offrirti una protezione aggiuntiva impostando un tempo di scadenza sul token originale. Quindi, se finisce per essere rubato o qualcosa del genere, sarebbe utile solo per un breve periodo di tempo.

Altrimenti, penso che dovresti avere informazioni sullo stato sul server. Non inserire nella lista nera i token, ma inserire nella whitelist la firma del token corrente.


2
Se supponi che alcuni dei tuoi client siano dannosi, è facile vedere che una sessione verrà copiata e riutilizzata e devi contrastarla sul server.
Michael Shaw,

1
Pessima idea, questa può essere utilizzata in seguito da un hacker, o semplicemente forzata ...
CROSP,

2
Immagina che un utente desideri disconnettersi da tutti gli altri dispositivi, non è possibile utilizzare JWT.
amd

@amd non è possibile? Che cosa succede se aggiungo nonce = (casuale) e se l'utente si disconnette, sostituisco il nonce. Sembra semplice ed efficace.
Simon B.

3

È possibile gestire i problemi JWT menzionati memorizzando un valore salt insieme all'utente e usando salt come parte del token per l'utente. Quindi, quando è necessario invalidare il token, basta cambiare il sale.

So che sono passati un paio d'anni ma ora lo farei diversamente. Penso che assicurerei che i token di accesso abbiano una durata relativamente breve, diciamo un'ora. Sarei anche sicuro di usare i token di aggiornamento che erano con stato sul server e quindi quando volevo terminare la sessione di qualcuno, avrei revocato il token di aggiornamento rimuovendolo dal server. Quindi dopo un'ora, l'utente verrebbe disconnesso e avrebbe dovuto riconnettersi per riottenere l'accesso.


4
Ma ancora una volta diventa pieno di stato in questo caso, quindi qual è il motivo per creare salt o usare qualsiasi altro approccio, puoi semplicemente archiviare il token nella tabella ed eliminare quando dovrebbe essere invalidato
CROSP

2
Puoi anche invalidare in base al tempo.
RibaldEddie,

Qual è la differenza tra il tempo di scadenza in questo caso? Come posso invalidare il token in base al tempo in cui l'utente desidera disconnettersi dal client mobile? Sembra che in questo caso l'API non possa essere apolide. Qual è la soluzione più adatta e sicura di?
CROSP,

2
Il più adatto per il logout da un singolo dispositivo è assicurarsi di utilizzare un clientId in aggiunta a Salt. Ti suggerisco di guardare le specifiche del token al portatore di Oauth-jwt per approfondimenti.
RibaldEddie,

Grazie per la risposta, ma non capisco perché dovrei usare OAuth in questo caso.
CROSP,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.