Gestione del rinnovo del token / scadenza della sessione in un'API RESTful

14

Sto costruendo un'API RESTful che utilizza i token JWT per l'autenticazione dell'utente (emessa da un login endpoint e inviata successivamente in tutte le intestazioni) e i token devono essere aggiornati dopo un periodo di tempo prestabilito (richiamando una renew endpoint, che restituisce un token rinnovato).

È possibile che la sessione API di un utente non sia più valida prima che il token scada, quindi tutti i miei endpoint iniziano verificando che: 1) il token è ancora valido e 2) la sessione dell'utente è ancora valida. Non c'è modo di invalidare direttamente il token, perché i client lo memorizzano localmente.

Quindi tutti i miei endpoint devono segnalare ai miei clienti due possibili condizioni: 1) che è il momento di rinnovare il token o 2) che la sessione è diventata non valida e che non sono più autorizzati ad accedere al sistema. Posso pensare a due alternative per i miei endpoint per segnalare ai loro clienti quando si verifica una delle due condizioni (supponiamo che i client possano essere adattati a entrambe le opzioni):

  1. Restituisce un codice http 401 (non autorizzato) se la sessione è diventata non valida o restituisce un codice 412 (precondizione non riuscita) quando il token è scaduto ed è ora di chiamare l'endpoint renew , che restituirà un 200 (ok) codice.
  2. Restituisce 401 per segnalare che la sessione non è valida o il token è scaduto. In questo caso il client chiamerà immediatamente l'endpoint renew , se restituisce 200 allora il token viene aggiornato, ma se renew restituisce anche 401 significa che il client è fuori dal sistema.

Quale delle due alternative sopra suggeriresti? Quale sarebbe più standard, più semplice da capire e / o più RESTful? O consiglieresti un approccio completamente diverso? Vedi qualche ovvio problema o rischio per la sicurezza con entrambe le opzioni? Punti extra se la tua risposta include riferimenti esterni che supportano la tua opinione.

Aggiorna

Ragazzi, concentratevi sulla vera domanda - quale delle due alternative del codice http per segnalare un annullamento di rinnovo / sessione è la migliore? Non importa che il mio sistema utilizzi JWT e sessioni lato server, questa è una peculiarità della mia API per regole di business molto specifiche, e non la parte per cui sto cercando aiuto;)

    
posta Óscar López 17.12.2016 - 17:02
fonte

3 risposte

17

Sembra un caso di autenticazione contro autorizzazione .

Le JWT sono dichiarazioni firmate crittograficamente sull'originatore di una richiesta. Una JWT potrebbe contenere affermazioni come "Questa richiesta è per l'utente X" e "L'utente X ha un ruolo di amministratore". Ottenere e fornire questa prova tramite password, firme e TLS è il dominio di autenticazione - provando che sei chi dici di essere.

Quali affermazioni significano sul tuo server - quali utenti e ruoli specifici sono autorizzati a fare - è il problema di autorizzazione . La differenza tra i due può essere descritta con due scenari. Supponiamo che Bob voglia entrare nella sezione di archiviazione riservata del magazzino della sua azienda, ma prima deve occuparsi di una guardia chiamata Jim.

Scenario A - Autenticazione

  • Bob: "Ciao Jim, vorrei entrare nello spazio di archiviazione limitato."
  • Jim: "Hai il tuo badge?"
  • Bob: "No, l'ho dimenticato."
  • Jim: "Mi dispiace amico, nessuna voce senza badge."

Scenario B - Autorizzazione

  • Bob: "Ciao Jim, vorrei entrare nella memoria riservata. Ecco il mio badge."
  • Jim: "Ehi Bob, hai bisogno del livello 2 per entrare qui. Scusa."

I tempi di scadenza JWT sono un dispositivo di autenticazione utilizzato per impedire ad altri di rubarli. Se tutti i tuoi JWT hanno cinque minuti di scadenza, non è un grosso problema se vengono rubati perché diventeranno presto inutili. Tuttavia, la regola della "scadenza della sessione" discuta sembra un problema di autorizzazione. Alcuni cambiamenti di stato indicano che l'utente X non è più autorizzato a fare qualcosa che era solito essere in grado di fare. Ad esempio, l'utente Bob potrebbe essere stato licenziato - non importa se il suo badge dice che è più Bob, perché semplicemente essere Bob non gli dà più alcuna autorità con la compagnia.

Questi due casi hanno codici di risposta HTTP distinti: 401 Unauthorized e 403 Forbidden . Il codice 401 sfortunatamente è per problemi di autenticazione come credenziali mancanti, scadute o revocate. 403 è per l'autorizzazione, dove il server sa esattamente chi sei ma non ti è permesso fare la cosa che stai tentando di fare. Nel caso in cui un account dell'utente venga eliminato, il tentativo di fare qualcosa con una JWT su un endpoint comporterebbe una risposta Proibita 403. Tuttavia, se il JWT è scaduto, il risultato corretto sarebbe 401 Non autorizzato.

Un modello JWT comune è quello di avere token "long life" e "short live". I token di lunga durata sono memorizzati sul client come token di breve durata, ma sono limitati nella portata e solo utilizzati con il tuo sistema di autorizzazione per ottenere token di breve durata. I token di lunga vita, come suggerisce il nome, hanno periodi di scadenza molto lunghi: puoi usarli per richiedere nuovi token per giorni o settimane. I token di breve durata sono i token che stai descrivendo, usati con tempi di scadenza molto brevi per interagire con il tuo sistema. I token di lunga durata sono utili per implementare la funzionalità Remember Me, quindi non è necessario fornire la password ogni cinque minuti per ottenere un nuovo token di breve durata.

Il problema di "invalidazione della sessione" che stai descrivendo sembra simile al tentativo di invalidare un JWT di lunga durata, poiché quelli di breve durata sono raramente archiviati sul lato server mentre quelli di lunga durata vengono tracciati nel caso in cui debbano essere revocati. In tale sistema, il tentativo di acquisire credenziali con un token di lunga durata revocato risulterebbe in 401 Non autorizzato, poiché l'utente potrebbe tecnicamente essere in grado di acquisire credenziali ma il token che stanno utilizzando non è adatto all'attività. Quindi, quando l'utente tenta di acquisire un nuovo token di lunga durata utilizzando il suo nome utente e la password, il sistema potrebbe rispondere con 403 Proibita se vengono cacciati dal sistema.

    
risposta data 18.12.2016 - 00:40
fonte
13

La tua sessione API è una cosa che non dovrebbe esistere in un mondo RESTful. Le operazioni RESTful dovrebbero essere apolidi, la sessione contiene lo stato e quindi non ha posto in un mondo RESTful.

Il JWT dovrebbe essere l'unico modo per determinare se un utente è ancora idoneo ad accedere a un endpoint o meno. Una sessione non dovrebbe assolutamente avere alcun ruolo in essa. Se lo fa, non hai un'API RESTful.

Quando elimini completamente la sessione, che se stai mirando a un'API RESTful dovresti fare e usa solo il JWT come fattore di autenticazione, un utente è autorizzato a utilizzare il tuo endpoint o meno - nel qual caso la% il codice di risposta di401 Unauthorized è appropriato, e dovrebbe chiamare l'endpoint renew con grant_type=refresh_token o qualsiasi identificazione del rinnovo che stai utilizzando.

Aggiornamento:

Dal commento sembra che il flusso di convalida del JWT attualmente in uso non sia corretto. La validazione dovrebbe assomigliare a questa:

  Client        RESTful API      JWT Issuer
     |              |                |
     |----- 1. ---->|                | 
     |              |------ 2. ----->|-----
     |              |                | 3. |
     |              |<----- 4. ------|<----
-----|<---- 5. -----|                |
| 6. |              |                |
---->|----- 7. ---->|                |
     |              |------ 8. ----->|-----
     |              |                | 9. |
     |              |<----- 10. -----|<----
     |              |                |
     |              |------          |
     |              | 11. |          |
     |<---- 12. ----|<-----          |
     |              |                |
     .              .                .

1. Ask RESTful API for a JWT using login endpoint.
2. Ask Issuer to create a new JWT.
3. Create JWT.
4. Return JWT to the RESTful API.
5. Return JWT to Client.
6. Store JWT to append it to all future API requests.
7. Ask for data from API providing JWT as authorization.
8. Send JWT to Issuer for verification.
9. Issuer verifies JWT.
10. Issuer returns 200 OK, verification successful.
11. Retrieve and format data for Client.
12. Return data to Client.

Il server, RESTful API , deve verificare la validità del token che viene inviato come Autorizzazione. Questa non è la responsabilità del Client . Sembra che attualmente non lo stai facendo. Implementa la verifica della JWT in questo modo e non hai bisogno di alcuna sessione.

    
risposta data 17.12.2016 - 18:23
fonte
1

Quindi, confesserò che non ha molto senso per me essere preoccupato dell'approccio più RESTful quando stai già violando le convenzioni REST con la sessione, ma capisco di soddisfare i tuoi requisiti aziendali.

Da un punto di vista REST, il client è autenticato o non lo è. L'architettura non si preoccupa molto del perché (che sta iniettando uno stato inutile), quindi per rispondere alla tua domanda principale, non avrei affatto un endpoint di rinnovo. Un client registrato invierà sempre il proprio JWT e il server lo convaliderà sempre e accetta o inviando il codice di successo appropriato in base all'azione 200, 201, ecc.) O rifiuta con un 401 o 403 a seconda dei casi.

Ora, il JWT sarà associato a un account di qualche tipo. Quell'account potrebbe essere bloccato o strozzato o qualsiasi altra cosa, e quindi il token stesso potrebbe essere valido ma l'azione sarà comunque respinta altrove. Se il caso è che l'account utente è bloccato a causa di regole di business, allora è ancora un 401 o 403 a seconda di quante informazioni si vuole dare al cliente (diverse imprese hanno opinioni diverse su quello).

Infine, se stai affermando che l'account potrebbe essere sbloccato e valido ma il JWT deve essere semplicemente revocato, allora STILL resterò con 401 o 403 e manterrò qualcosa come un elenco di revoche di certificati di JWT non validi che puoi inserire uno in, fintanto che si ripulisce quando il JWT sarebbe scaduto (la maggior parte dei database ha un modo per farlo o si possono avere eventi nel codice app).

    
risposta data 18.12.2016 - 00:50
fonte

Leggi altre domande sui tag