Sicurezza dell'API REST Segno memorizzato vs JWT vs OAuth

92

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 alcuni malintesi, quindi ho bisogno di consigli di qualcuno più esperto.

Lasciami dire, come capisco tutto questo. Se capisco qualcosa in modo errato, per favore fatemelo sapere.

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

  1. Token con HTTPS. Ho usato questo approccio un sacco di volte è abbastanza buono con HTTPS. Se l'utente fornisce la password e il login corretti, riceverà il token in risposta e lo userà per ulteriori richieste. Il token è generato dal server e memorizzato, ad esempio nella tabella separata o uguale dove sono archiviate le informazioni dell'utente. Quindi per ogni richiesta il server controlla se l'utente ha 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ò cambiare ad esempio la data di scadenza o qualsiasi altro reclamo, poiché questo token è generato (firmato) dal server con una parola chiave segreta. Questo è anche 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. Per 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 vuole iscriversi su qualche pagina, il server può richiedere le autorizzazioni per ottenere informazioni sugli utenti, ad esempio da Twitter o Facebook, e riempire i campi di registrazione con i dati dell'utente e così via.

Considera il client mobile per il negozio online.

Prima domanda dovrei preferire JWT al primo token di tipo? Per quanto ho bisogno di login / logout utente su client mobile, ho bisogno di memorizzare qualche token o in caso di JWT, il token dovrebbe essere invalidato al logout. Diversi approcci sono utilizzati per invalidare il token uno dei è quello di creare un elenco di token non valido (lista nera). Hmm. Tabella / file avrà dimensioni molto più grandi di se il token è stato memorizzato nella tabella e associato all'utente, e appena rimosso al logout.

Quindi quali sono i vantaggi del token JWT?

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

    
posta CROSP 04.10.2015 - 21:22
fonte

3 risposte

77

Considera il primo caso. Ogni cliente riceve un ID casuale che dura per la durata della sessione, che potrebbe essere di diversi giorni se lo desideri. Quindi memorizzi le informazioni rilevanti per 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 utilizzare l'URL o un'intestazione HTTP.

ID sessione / cookie

Pro:

  • Facile codificare sia il client che il server.
  • Facile distruggere una sessione quando qualcuno si disconnette.

Contro:

  • Il lato server deve periodicamente eliminare le sessioni scadute in cui il client non ha effettuato il logout.
  • Ogni richiesta HTTP richiede una ricerca nell'archivio dati.
  • I requisiti di archiviazione aumentano man mano che più utenti hanno sessioni attive.
  • Se ci sono più server HTTP front-end i dati della sessione archiviati devono essere accessibili da tutti loro. Questo potrebbe essere un po 'più di lavoro che memorizzarlo su un server. I problemi più grandi sono che 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 sono memorizzati in un JWT che viene passato in giro invece che sul server.

Pro:

  • I problemi di archiviazione sul lato server sono andati.
  • Il codice lato client è facile.

Contro:

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

    Chiunque riceve una copia della chiave di firma può creare JWT. Potresti non sapere quando succede.

    C'era (è?) 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 avrebbe fiducia.

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

OAuth

Spesso OAuth viene utilizzato per l'autenticazione (ad esempio 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 usato per concedere l'accesso per scrivere ai dati memorizzati da terzi. È possibile utilizzare OAuth per autenticare gli utenti e quindi utilizzare l'archiviazione lato server o JWT per i dati della sessione.

Pro:

  • Nessun codice per consentire agli utenti di registrarsi o reimpostare la propria password.
  • Nessun codice per inviare un'email con un link di convalida e quindi convalidare l'indirizzo.
  • Gli utenti non hanno bisogno di imparare / scrivere un altro nome utente e password.

Contro:

  • Si dipende dalla terza parte per consentire agli utenti di utilizzare il servizio. Se il loro servizio si interrompe o lo interrompono, allora devi capire qualcos'altro. Ad esempio: come si fa a migrare i dati dell'account dell'utente se la loro identità cambia da "[email protected]" a "[email protected]"?
  • Di solito devi scrivere il codice per ogni provider. ad es. Google, Facebook, Twitter.
  • Tu o i tuoi utenti potreste avere problemi di privacy. I fornitori sanno quali dei loro utenti usano il tuo servizio.
  • Ti stai fidando del fornitore. È possibile che un fornitore emetta token validi per un utente a qualcun altro. Questo potrebbe essere per scopi leciti o meno.

Varie

  • 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 effettuare il roaming, ad esempio da Wi-Fi a cellulare.
risposta data 26.01.2016 - 21:07
fonte
5

Chiediti perché hai bisogno di invalidare il token originale.

Un utente accede, un token viene generato e fuori dall'app.

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

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

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

Puoi concederti una protezione aggiuntiva mettendo un tempo di scadenza sul token originale. Quindi se finisce per essere rubato o qualcosa, allora sarebbe buono solo per un breve periodo di tempo.

Altrimenti, penso che avresti bisogno di avere informazioni di stato sul server. Non aggiungere token di blacklist ma invece autorizzare la firma del token corrente.

    
risposta data 05.10.2015 - 16:43
fonte
3

Puoi gestire i problemi JWT menzionati memorizzando un valore salt insieme all'utente e utilizzando il salt come parte del token per l'utente. Quindi, quando hai bisogno di invalidare il token, cambia semplicemente il sale.

So che sono passati un paio d'anni ma ora lo farei in modo diverso. Penso che farei in modo che i token di accesso abbiano una durata relativamente breve, ad esempio un'ora. Sarei anche sicuro di utilizzare i token di aggiornamento che erano stateful sul server e poi quando volevo terminare la sessione di qualcuno, avrei revocato il token di aggiornamento rimuovendolo dal server. Quindi, dopo un'ora, l'utente verrà disconnesso e dovrà accedere di nuovo per riottenere l'accesso.

    
risposta data 05.10.2015 - 01:40
fonte

Leggi altre domande sui tag