Progettazione dell'autenticazione per l'API REST


11

Sto lavorando a un'API per un servizio REST che sto per produrre e consumare. Ho passato gli ultimi giorni a cercare di capire come gestire l'autenticazione in modo corretto e penso di aver finalmente escogitato qualcosa.

Sto arrivando a questo sulla base dei seguenti fatti sullo stack dell'applicazione:

  1. Client e server sono in .NET4 (parte client nel profilo client)
  2. Il server espone usando WCF REST
  3. Non voglio davvero conservare il nome utente e la password nell'app

Da 3, volevo usare una forma di autenticazione token, in modo che dopo che le credenziali sono state verificate dal server, il client ottiene un token di nuovo da usare in tutto il resto dell'app (questo mi permetterà di fare altre cose, come timeout degli utenti, essere in grado di spostarli senza soluzione di continuità tra le versioni web e desktop, ecc.). Dopo aver capito come rendere le chiamate replay e antimanomissione, ho pensato a quanto segue:

  1. Prima che il client tenti di autenticarsi, genera una coppia di chiavi Diffie-Hellman usando la ECDiffieHellmanCngclasse.
  2. Invia la parte pubblica della coppia di chiavi sul filo insieme al nome utente e alla password (ovviamente su HTTPS).
  3. Il server autentica la combinazione nome utente / password, se ha esito positivo, procede come segue:
    1. Crea un token di sessione unico
    2. Genera la propria coppia di chiavi DH e calcola il segreto condiviso dalla chiave pubblica fornita dal client
    3. Annota il token di sessione, il segreto condiviso, l'utente e l'ora "ultima azione" (utilizzata per una finestra di scadenza a rotazione) nel suo database
    4. Restituisce il token di sessione, la sua chiave DH pubblica e un messaggio di successo dell'autenticazione
  4. Il client prende la chiave DH dalla risposta, calcola il segreto condiviso e memorizza sia il token che il segreto in memoria.

Da questo punto in poi, la combinazione token / segreta di sessione funziona come la maggior parte delle altre API REST, con la richiesta di impronte digitali e timestamp, e quindi genera una sorta di HMAC. Ogni volta che un client esegue un'azione sul server, controlla la coppia token / segreta e consente l'azione se è valida e non scaduta e aggiorna l'ultimo record di azioni nella sessione.

Non vedo alcun difetto ovvio, e probabilmente è troppo ingegnerizzato per questo, ma ho bisogno di imparare come farlo ad un certo punto. L'HMAC previene gli attacchi replay, la negoziazione DH aiuta a prevenire gli attacchi MITM (non riesco a pensare a un attacco praticabile dalla cima della mia testa tra HMAC / DH).

Qualche buco che qualcuno può fare in questo?


Non vedo come la generazione delle chiavi DH aggiunga alcuna sicurezza rispetto al semplice utilizzo di HTTPS ovunque e all'utilizzo di semplici cookie di vecchia sessione. Se usato correttamente, HTTPS protegge già dagli attacchi man-in-the-middle e replay.
Lie Ryan,

Risposte:


5

Invece di inventare il tuo, dovresti considerare di leggere l'API OpenAM e prenderla in prestito.

http://forgerock.com/openam.html

OpenAM Wiki è particolarmente utile

https://wikis.forgerock.org/confluence/display/openam/Home

Non è necessario utilizzare i loro componenti. Ma se usi la loro API, scoprirai che la tua vita sarà più semplice a lungo termine.


Hmm, non sembra male, una cosa che mi impedisce di usarlo in questo caso: siamo un negozio .Net. Inoltre, non c'è molto sull'usarlo con il lato server WCF delle cose. L'unico link non spammy che ho trovato su Google a questo proposito punta all'utilizzo di WIF e WS-Federation.
Matt Sieker,

1
@Matt Sieker: "Non è necessario utilizzare i loro componenti". Leggi le loro API invece di inventare le tue.
S.Lott

Ah, penso di vedere cosa intendi, i requisiti di richiamata. Questo è interessante, potrei approfondire questo, se non per questo progetto, per quelli futuri. Invece di fare l'autenticazione come un singolo blocco atomico, suddividilo leggermente, in modo che il server possa controllare ciò di cui ha bisogno dal client ...
Matt Sieker

Inizialmente abbiamo creato il nostro ma poi ci siamo trasferiti ad OpenAM diversi anni fa presso IG Group. Molto soddisfatto del prodotto open source.
Robert Morschel,

2

Sono d'accordo al 100% con @ S.Lott sul fatto che non desideri pubblicizzare il tuo. Suggerisco di cercare un'altra alternativa: il servizio di controllo degli accessi (ACS) di Windows Azure. L'ACS costa denaro, ma è molto economico (10.000 transazioni per $ 0,01) e viene gestita una buona parte dell'infrastruttura. WIF è sfruttato sul client.

Questa è anche una soluzione basata su standard / attestazioni - che è di gran moda. Dai un'occhiata a questo articolo sull'uso insieme di WCF, REST e ACS .

Se stai pensando al futuro, questo è anche un meccanismo che può crescere con te, poiché hai app mobili al di fuori del firewall, dei partner e così via. Anche se non si desidera utilizzarlo poiché aggiunge una dipendenza al di fuori del firewall, è possibile verificarlo per idee. Molto lucido.

In bocca al lupo! -Conto

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.