Migliorare il token di autenticazione dell'API REST stateless o eliminarlo per la persistenza del database?

1

Sto cercando di implementare l'autenticazione REST stateless in un'API. Ho letto gli articoli qui e ho implementato un'idea che funziona, ma speravo di ottenere un feedback sulla sua sicurezza e su eventuali miglioramenti.

  1. L'autenticazione iniziale avviene tramite l'autenticazione di base HTTPS. Username e password sono forniti in testo semplice.

  2. Il server genera e fornisce un token fornito al client, ma non è archiviato nel database. Tutti gli articoli che ho letto sui token auth suggeriscono di memorizzare non il token stesso , ma alcuni valori che possono essere sottoposti a hash con un altro valore (il nome utente, ecc.) Per generare nuovamente il token e convalidarlo - ma io pensavo che il punto di un'API REST fosse stateless, e not non memorizza alcun token / valore correlato all'autore?

  3. Questo token viene quindi utilizzato per richieste successive al posto di richiedere sempre il nome utente / password nelle intestazioni.

Il token

Il token è generato usando:

encrypt(username, salt, hash, expirationDate)

Dove encrypt è reversibile usando attualmente un DES Cipher , ma in futuro probabilmente una chiave privata o una risorsa memorizzata sul server che può essere facilmente sostituita senza fare affidamento su un valore nel codice sorgente .

Il vantaggio è che questo consente al server di decrittografare il token in entrata e confrontare il sale / hash con ciò che è memorizzato nell'oggetto modello User . (Che ha salt e hash proprietà memorizzate nel database.)

Le preoccupazioni che ho con questo:

  1. Se la chiave privata o la Cipher password sono note, questi token possono essere falsificati.

  2. Ho preso in considerazione l'utilizzo di password invece di salt e hash , ma non mi piaceva l'idea che password fosse noto se si trova la chiave privata o la password Cipher .

Quindi: c'è un modo migliore per fare questo tipo di autenticazione con codice "decryptable"? E vale la pena mantenere questo obiettivo "stateless" di REST, o dovrei semplicemente memorizzare una versione hash del token e username (ma not il token stesso) nel database e lanciare l'apolide auth "idea fuori dalla finestra?

    
posta Craig Otis 05.10.2014 - 01:36
fonte

2 risposte

2

Penso che tu abbia frainteso il vincolo "senza stato" di REST. Da ciò che è stato scritto in Dr. La tesi di Fielding , si può avere l'impressione sbagliata che stateless significa non conservare (sul lato server) alcuna informazione sul client, il che è sbagliato. Quello che intendeva dire era che il server non doveva mantenere nulla relativo alla sessione del client (stato del client, che può cambiare durante la sua manutenzione), che è una cosa diversa.

Ad esempio, se il tuo servizio web dovesse supportare più utenti, dovresti mantenere le informazioni sui tuoi utenti, insieme alle loro credenziali, in modo da poter convalidare ogni richiesta e confermare che proviene da un utente valido dal tuo sistema.

Ciò che non dovresti mantenere è lo stato in cui si trova un utente durante l'utilizzo del servizio. Dai un'occhiata a questa frase della tesi:

Scalability is improved because not having to store state between requests allows the server component to quickly free resources, and further simplifies implementation because the server doesn't have to manage resource usage across requests.

Quindi, se memorizzi lo stato dei tuoi clienti sulla tua macchina di servizio, i limiti di archiviazione potrebbero essere raggiunti rapidamente, con ogni nuovo utente aggiunto al sistema, per non parlare dello scenario in cui un singolo utente può avere più richieste simultanee e devi gestire le risorse attraverso ciascuna di queste richieste. Inoltre, se uno dei computer di servizio si arresta, qualsiasi altro computer di servizio disponibile non sarà in grado di occuparsi del client e continuare a servirlo, poiché lo stato di quel client, che è stato tenuto sul computer del servizio non funzionante, viene perso .

Per farla breve, non hai davvero bisogno di sessioni per i servizi REST. Assicurati solo che la tua comunicazione sia protetta (HTTPS) e puoi inviare le informazioni di base con ogni richiesta. Se sei veramente interessato alla sicurezza, prova ad usare hmac o oauth o anche certificato per client. Ma assicurati di non memorizzare alcuna sessione sui tuoi computer di servizio.

Nota che questo non significa che non puoi utilizzare servizi di autenticazione esterni, che non devono essere RESTful, come i server Single Sign-On.

    
risposta data 11.11.2015 - 12:42
fonte
0

Spero che tu intenda 3DES, o forse DES è stato un errore di battitura e intendi AES? Un singolo DES può essere facilmente rotto in questi giorni.

Ad ogni modo, perché hai bisogno che sia decifrabile? Un modello ragionevole per generare un token di autenticazione sarebbe qualcosa come questo pseudocodice:

raw_token = userid + ':' + expiration_time
sig = HMAC(raw_token, service_key)
token = raw_token + ':' + sig

Quindi, quando viene ricevuta una richiesta, è possibile verificare il token suddividendo la firma, ricalcolando e verificando l'HMAC e quindi controllando che non sia trascorso il tempo di scadenza.

Sì, proprio come descrivi, questo ha la proprietà che se la chiave diventa nota, è possibile falsificare i token. Ciò sarebbe inerente a qualsiasi sistema che utilizza token crittografici per l'autenticazione e l'unica alternativa è il modello "genera un token casuale e lo memorizza anche sul lato server".

    
risposta data 05.10.2014 - 06:14
fonte

Leggi altre domande sui tag