Come gestire i token di aggiornamento

2

Sto provando a racchiudere l'autenticazione basata su JWT (JSON Web Token) per la protezione degli endpoint API utilizzando i token di accesso. Sto proteggendo questi endpoint richiedendo all'utente di avere un token di accesso valido per ottenere tali risorse.

Sto lottando, tuttavia, comprendendo l'uso di un token di aggiornamento.

Ho un endpoint / auth / login che accetta% richieste diPOST:

class UserLogin(Resource):
    def post(self):
        data = parser.parse_args()
        current_user = User.find_by_username(data['username'])
        if not current_user:
            return {'message': 'Unsuccessful. You do not have an account'}

        if User.verify_hash(data['password'], current_user.password):
            access_token = create_access_token(current_user)
            refresh_token = create_refresh_token(current_user)
            return {
                'message': 'Login successful {}'.format(current_user.username),
                'roles': 'Role: {}'.format(current_user.role),
                'access token': access_token,
                'refresh token': refresh_token
            }
        else:
            return {'message': 'Something went wrong'}

Il punto finale controlla essenzialmente le credenziali in entrata per garantire che l'utente esista nel mio archivio utente. Se lo fanno, restituirò un token di accesso e aggiornamento. In caso contrario, verrà gestito un messaggio di errore sul lato client.

Ora, supponiamo che l'utente abbia effettuato l'accesso e provi ad accedere a una risorsa privata da un altro endpoint protetto richiedendo un token di accesso. Il client eseguirà una richiesta e l'endpoint protetto restituirà alcuni messaggi di errore che indicano che non hanno un token di accesso. Il client tenterà quindi di generare un nuovo token di accesso utilizzando il token di aggiornamento ottenuto all'accesso:

class TokenRefresh(Resource):
    @jwt_refresh_token_required
    def post(self):
        current_user = get_jwt_identity()
        access_token = create_access_token(identity=current_user)
        return {'access token': access_token}

Colpendo la risorsa precedente genererà un nuovo token di accesso con una certa scadenza definita. Questo è il mio flusso attuale.

La mia domanda è, come devo conservare i token di aggiornamento per assicurarmi che vengano acceduti dall'utente autenticato? Dovrei avere qualche logica aggiuntiva nelle mie richieste di accesso che memorizzano il token di aggiornamento generato per quell'utente specifico?

In tal caso, dovrei quindi generare un nuovo token di aggiornamento e sovrascrivere il token di aggiornamento esistente collegato all'utente ogni volta che il client tenta di aggiornare il proprio token di accesso?

Al momento, ritengo che il mio processo possa essere compromesso se un utente malintenzionato riesce a ottenere il token di aggiornamento.

    
posta Sam 30.09.2018 - 13:47
fonte

2 risposte

1

Il punto di avere token di accesso è che possono essere utilizzati senza verificare l'invalidazione. È possibile avere 10000 server front-end che gli utenti possono accedere con il token senza dover chiedere il database se non è valido. Ma dopo qualche tempo, il token scade. L'utente ha bisogno di un nuovo token di accesso, invia il suo token di aggiornamento e questo token di aggiornamento viene controllato in alcuni database. Non è mai necessario verificare i token di accesso scaduti o avere uno stato, ma limitare l'abuso alla durata del token.

Se non hai l'obbligo di accettare i token senza controllare la scadenza in un database, non hai bisogno dei due diversi token. Puoi semplicemente utilizzare il token di aggiornamento per ciascun accesso.

Esempio di flusso di lavoro sarebbe:

  1. L'utente accede, ottiene l'accesso e aggiorna il token. Durata del token di accesso 15 minuti, aggiornamento del token 5 giorni.

  2. L'utente accede al servizio utilizzando il token di accesso. Il servizio controlla solo la firma e la durata. Nessuna connessione al database.

  3. L'utente si disconnette, il token di aggiornamento è contrassegnato come scaduto nel database
  4. L'utente accede al servizio utilizzando il token di accesso, questo funziona ancora
  5. 15 minuti. Il token di accesso scade, l'utente richiede un nuovo token di accesso utilizzando il token di aggiornamento ancora nel corso della sua vita. Il servizio controlla il database e scopre che il token è scaduto. L'utente non può ottenere un nuovo token di accesso.

L'intero sistema è un compromesso tra il tempo necessario per invalidare le sessioni e la quantità di connessioni a un'origine dati condivisa / sincronizzata richiesta.

Puoi sostituire il token di aggiornamento su ciascun aggiornamento, ma ricorda che è necessario archiviare tutti i token di aggiornamento scaduti fino al termine della vita .

Dal punto di vista della sicurezza ha senso creare un nuovo token, ma è un compromesso tra sicurezza e quantità di dati nel tuo database.

Nel peggiore dei casi (nessuna durata per i token di aggiornamento, mai farlo) ora devi memorizzare un token ogni pochi minuti nel database per ogni utente invece di un token per ogni utente e tu non potrà mai più rimuoverli.

    
risposta data 18.10.2018 - 13:25
fonte
0

I token di aggiornamento sono una di quelle tecnologie in cui la pratica e la teoria non corrispondono, nella mia esperienza. In teoria, si effettua una richiesta di accesso e si ottiene un token di accesso (con una breve durata) e un token di aggiornamento (che ha un lungo periodo di scadenza, senza scadenza e può essere utilizzato per ottenere un nuovo token di accesso in qualsiasi momento ). Se il client tenta di inviare un token di accesso scaduto e ottiene un rifiuto dal server, può inviare il token di aggiornamento, ottenere un nuovo token di accesso, quindi continuare.

In questo caso, è molto chiaro che il token di aggiornamento è davvero potente e deve essere archiviato con cura (ad esempio nell'archiviazione delle credenziali su un dispositivo mobile, piuttosto che un cookie del browser o in un archivio lato server attentamente protetto) . Tuttavia, le specifiche consentono che un token di aggiornamento venga invalidato dal server di autenticazione.

In pratica, quindi, non è raro che un token di aggiornamento venga rilasciato al momento dell'accesso e invalidato al logout o dopo un periodo di inattività. In questo caso, può essere parte dei dati di sessione sul server e quindi automaticamente collegato all'utente corrente. Qualsiasi altro utente sarebbe in grado di utilizzare il token di aggiornamento solo all'interno della sessione autenticata, il che significa che anche qualsiasi logica che lo collega a un utente specifico fallirebbe.

Dal frammento di codice sopra, questo è praticamente quello che hai: il token di aggiornamento viene generato ogni accesso, piuttosto che essere recuperato dallo spazio di archiviazione dopo essere stato generato durante la creazione dell'account, ad esempio. L'unica parte mancante è il modo in cui viene interrogato il token di aggiornamento: è implicito che il token di aggiornamento sia considerato sufficiente per ottenere un token di accesso, anziché la combinazione di una sessione autenticata e un token di aggiornamento. Questo è, come sospetti, insicuro.

Il token di aggiornamento fornisce l'autorizzazione per ottenere un nuovo token di accesso, ma non autentica il fatto che la persona che richiede il token di accesso sia quella che dovrebbe avere accesso. È necessario fornire la fase di autenticazione prima di accettare l'autorizzazione e assicurarsi che venga utilizzata ogni volta che viene utilizzato il token di aggiornamento: una sessione aperta potrebbe essere sufficiente.

È possibile scegliere di sostituire il token di aggiornamento su ogni nuovo token di accesso. Questo ha un vantaggio collaterale di rottura in modo evidente se più utenti tentano di utilizzare il token di aggiornamento (il secondo fallisce), limitando quindi l'uso simultaneo. Evitare l'emissione di nuovi token di aggiornamento senza scadere di quello vecchio, tuttavia, poiché ciò aumenta il potenziale di compromissione di token. È probabilmente di beneficio limitato nel caso in cui il token di aggiornamento scada con la sessione (presupponendo una breve durata della sessione), ma può essere d'aiuto con sessioni più lunghe (ad esempio funzioni "ricordami").

    
risposta data 18.10.2018 - 11:31
fonte

Leggi altre domande sui tag