Autenticazione basata su token che utilizza i token di accesso e aggiornamento

8

Sto implementando un sistema di autenticazione basato su token per un'API REST che utilizza un token di accesso di breve durata e un token di aggiornamento di lunga durata. Questa è una panoramica astratta degli endpoint API pertinenti (HTTPS viene applicato per tutti gli endpoint):

Endpoint:

POST /register/
POST /login/
POST /logout/
POST /password/change/

Implementazione:

POST /register/ :

  • Richiesta: il client invia nome utente, email e password in JSON.
  • Azioni server:
    1. Convalida l'input, crea l'utente nel database (memorizza l'id utente, il nome utente, l'e-mail e l'hash della password).
    2. Crea token di accesso di breve durata in formato JWT (contiene ID utente, data di emissione e data di scadenza).
    3. Crea token di aggiornamento a vita lunga come stringa UUID e lo memorizza nel database (memorizza l'ID utente e il token di aggiornamento).
  • Risposta: il server restituisce il token di accesso e aggiorna il token in JSON.

POST /login/ :

  • Richiesta: il client invia nome utente e password in JSON.
  • Azioni server:
    1. Convalida l'input, controlla se le credenziali sono valide controllando il database.
    2. Se le credenziali sono valide, crea token di accesso di breve durata e token di aggiornamento a vita lunga come menzionato in precedenza.
  • Risposta: come /register/ , restituisce il token di accesso e aggiorna il token in JSON.

POST /logout/ :

  • Richiesta: il client invia il token Aggiorna nell'intestazione Authorization come token Bearer .
  • Azioni server:
    1. Convalida il token di aggiornamento controllando il database dei token di aggiornamento.
    2. Rimuove il token di aggiornamento dal database.
      Nota: questo lascia il token di accesso valido, ma dal momento che sarà di breve durata (1 ora o giù di lì, penso che dovrebbe andare bene ).
  • Risposta: restituisce se la richiesta di disconnessione è stata elaborata correttamente in JSON.

POST /password/change/ :

  • Richiesta: il client invia il token accesso nell'intestazione Authorization come token Bearer e invia anche la vecchia password e la nuova password in JSON tramite HTTPS.
  • Azioni server:
    1. Decodifica il token di accesso per recuperare l'utente e controlla la vecchia password dell'utente con il database.
    2. Imposta l'hash della password dell'utente nel database sull'hash della nuova password.
    3. Rimuove tutti i token di aggiornamento associati con l'utente nel database dei token di aggiornamento per disconnettere essenzialmente le sessioni esistenti (lasciano validi token di accesso di breve durata validi).
  • Risposta: restituisce se la richiesta di modifica della password è stata elaborata correttamente in JSON.

Domande:

  1. Questo approccio è sicuro? In particolare:
    • L'invio del nome utente e della password tramite JSON safe avviene su HTTPS? Come impedire ai domini non autorizzati di effettuare chiamate a questo endpoint? Inoltre, come impedirei gli accessi programmatici?
    • I token di aggiornamento devono essere sottoposti a hash prima di archiviarli nel database o sono solo paranoico?
  2. Se il client fosse un browser web, come conserverei in modo sicuro il token di aggiornamento sul client?
    • Un'idea che ho per memorizzare il token di aggiornamento è: quando l'utente esegue l'accesso, oltre a inviare il token di aggiornamento al client, il server memorizza il token in un cookie HttpOnly con un flag secure . L'autorizzazione verrà comunque eseguita tramite l'intestazione Authorization , ma quando il client si carica inizialmente, può inviare una richiesta di GET a un endpoint che verifica se il cookie contiene un token di aggiornamento valido e, in caso affermativo, restituirlo al utente in JSON. In altre parole, l'unica volta in cui il cookie verrà effettivamente utilizzato è quello di restituire il token di aggiornamento all'interno del cookie al client. Questo approccio è sicuro? Penso che impedirà CSRF perché non ci sono effetti collaterali quando si richiede il token di aggiornamento dal cookie, ma esiste un altro modo in cui un utente malintenzionato potrebbe intercettare il token di aggiornamento (supponendo HTTPS)?
posta Kootling 30.06.2017 - 21:21
fonte

1 risposta

2

Is this approach secure? Specifically:

  • Is sending the username and password through JSON safe if done over HTTPS?

Sì. Le intestazioni, i parametri di richiesta e il corpo della richiesta vengono crittografati durante la comunicazione.

Una volta sul lato server, non registrare il corpo della richiesta: -)

  • How would I prevent unauthorised domains from making calls to this endpoint?

Non puoi. Fondamentalmente, una volta che l'API è sul WWW, viene automaticamente esposta a qualsiasi tipo di malizia. Il meglio che puoi fare è essere preparati e essere consapevoli delle minacce. Almeno su quelli che ti riguardano. Dai un'occhiata qui .

Un possibile approccio al problema potrebbe essere l'implementazione (o la contrazione) di un gestore API .

I responsabili API on-premise possono ridurre la superficie di attacco perché tutti gli endpoint dietro l'AM non sono necessariamente pubblici.

Potresti ottenere lo stesso risultato con alcuni prodotti nel cloud, ma sono assurdamente costosi per il mainstream.

Comunque, gli endpoint della gestione API rimarranno esposti agli attacchi.

  • Furthermore, how would I prevent programmatic logins?

Se per accessi programmatici intendi attacchi con forza bruta, una soglia (numero massimo di richieste consentite al secondo) e una lista nera dovrebbero essere sufficienti a scoraggiare l'insistenza dell'attaccante. Per ulteriori informazioni, dai un'occhiata a qui .

Molti gestori API forniscono configurazioni predefinite del limite di frequenza API e Whitelist .

Se hai familiarità con la Console dell'API di Google, puoi indovinare cosa può fare un gestore API.

  • Should the refresh tokens be hashed before storing them in the database, or am I just being paranoid?

Se il token di aggiornamento è un semplice UUID o altro, non mi piace esporre questo tipo di dettagli di implementazione. Quindi suggerirei di cancellarlo. Per me, più opachi sono i dettagli di implementazione del livello di sicurezza, meglio è.

Per quanto riguarda la sicurezza JWT, dai un'occhiata a qui .

  • If the client were a web browser, how would I securely store the refresh token on the client?

Potresti essere interessato a JSON Web Token (JWT) - Archiviazione sul lato client .

    
risposta data 30.06.2017 - 23:11
fonte

Leggi altre domande sui tag