web-services - Autenticazione per i servizi Web REST




authentication oauth openid (7)

Il mio suggerimento è di autenticare la prima richiesta e quindi impostare un token di sessione.

L'applicazione front-end memorizzerebbe il token e lo fornirà con ogni richiesta successiva.

Il token avrebbe una scadenza. Il token scadrà se non viene utilizzato per un certo periodo.

Il token può essere associato all'indirizzo IP di origine per maggiore sicurezza.

Il token può essere trasmesso come cookie o come uno dei parametri di query nell'URL.

Se il fastidio dell'autenticazione del client SSL è accettabile, è possibile utilizzare l'autenticazione SSL reciproca. Ogni cliente dovrebbe essere fornito con un certificato che il server considera affidabile. Può essere lo stesso certificato o diversi certificati se devi trattare i clienti in modo diverso.

Sto iniziando a progettare un servizio web REST e non sono chiaro sul miglior approccio all'autenticazione. Il servizio consentirà ai singoli utenti di accedere / gestire i propri dati, quindi è richiesto un certo tipo di autenticazione dell'utente. Ho visto queste opzioni:

  • OAuth

OAuth sembra essere più sull'autorizzazione che sull'autenticazione. Ho intenzione di gestire l'autorizzazione in modo nativo all'interno dei servizi, quindi non sto cercando una soluzione a questo. Ma OAuth è appropriato anche per l'autenticazione?

  • OpenID

OpenID fornisce certamente una soluzione per l'autenticazione, ma è più orientata a consentire agli utenti di utilizzare le proprie credenziali di terze parti (Google, Yahoo, ecc.). Anche se mi piacerebbe sostenerlo, questa non è una preoccupazione primaria per me, e lo farò sicuramente consentire agli utenti di registrarsi con credenziali native (email / password).

  • Autenticazione di base HTTP

È semplice da implementare, ma è a mia conoscenza che questo potrebbe non essere un metodo molto sicuro. Inoltre, sembrerebbe richiedere lo scambio di credenziali per ogni accesso, ma preferirei che l'utente effettui l'autenticazione una volta e poi continui l'accesso tramite un token di sessione.

  • Autenticazione personalizzata

Fondamentalmente, roll il mio servizio di login / generazione di token e richiedono un token valido per l'accesso a tutte le altre risorse (ovviamente, tutto sarebbe su SSL).

Oltre a creare i servizi Web, creerò anche un'applicazione client (web) che utilizza questi servizi per conto di un utente, ma non voglio che l'applicazione debba memorizzare informazioni / credenziali utente / ecc. Quindi, qualcosa del genere:

Utente (autentica con e-mail / password o credenziali di terze parti) -> Applicazione Web (autentica con ID applicazione) -> Servizi Web

E ancora, voglio consentire ad altri di creare client, quindi il middle tier può essere qualsiasi applicazione di terze parti:

Utente (autentica con e-mail / password o credenziali di terze parti) -> Applicazione di terze parti (si autentica con l'ID dell'applicazione) -> Servizi Web

I miei requisiti di altissimo livello sono:

  • Sicuro (ovviamente)
  • Credenziali native
  • Supporto per le credenziali di terze parti (Google, Yahoo, LinkedIn, ecc.)
  • Supporto di più client (app Web, app per dispositivi mobili, app di terze parti, ecc.)
  • Credenziali del cliente (solo un ID app?)
  • Sessioni di accesso che scadono
  • L'autorizzazione NON è richiesta

Quindi, la mia domanda è, sulla base di quanto sopra (per favore fatemi sapere se questo è troppo vago), c'è un approccio "migliore"? OAuth o OpenID sono appropriati, o lo sto rendendo troppo complicato, e invece dovrei semplicemente eseguire la mia autenticazione?

MODIFICARE:

Penso che dovrò implementare quanto segue:

1) Credenziali / token nativi (autenticazione di base HTTP su SSL?)

2) Un OpenID "Relying Party" per consentire alla mia API di utilizzare OpenIDs ospitati altrove (ad esempio, "supporto per le credenziali di terze parti")

3) Un "consumatore" di OAuth per consentire alla mia API di accedere a servizi di terze parti (come l'accesso al profilo LinkedIn di un utente).

4) Un "Provider" OpenID per consentire alle persone di utilizzare gli ID nativi dell'api altrove (opzionale)

5) Un "provider" OAuth per consentire alle app di terze parti di accedere alla mia API per conto degli utenti (facoltativo)

Questo sembra giusto, o sto rendendo questo più complicato di quanto debba essere?


In base alle tue esigenze, penso che OAuth 2.0 potrebbe effettivamente essere un'opzione interessante. OAuth è infatti un protocollo di autorizzazione, ma Authenticates anche il client con un clientId e un clientSecret . Puoi utilizzare il Client Credential Flow del Client Credential Flow e scegliere di non includere un Refresh Token , in questo modo l'utente ha un Access Token , che scade dopo un certo periodo di tempo. E poiché OAuth è un protocollo ampiamente utilizzato, ci sono già molte librerie client e server side da utilizzare per te e per i tuoi clienti.

Se pensi che OAuth sia troppo pesante o troppo complicato per la tua applicazione, probabilmente mi collegherei con l' Basic Authentication su HTTPS . Ma come ho anche affermato in un'altra risposta a una domanda simile, non avrei mai inventato il mio meccanismo di autenticazione.

Per maggiori informazioni puoi anche dare un'occhiata all'altra risposta che ho dato in precedenza a una domanda simile: https://.com/a/15003777/849741


Potresti usare l'autenticazione di base HTTP, dove la password trasferita non è in realtà una password ma un token, che il cliente ha acquisito su una diversa richiesta di risorse, dove ha dovuto fornire la sua password una volta e una sola volta ( forse anche su un altro canale). Questo non protegge gli attacchi man-in-the-middle (dato che non c'è la firma del messaggio), ma l'idea è che puoi sempre richiedere al client di generare un token dinamico in qualche modo (cioè su un servizio di autenticazione tuo) e poi è necessario inviare quel token come sostituzione della password, quindi la password effettiva non viene trasferita costantemente sul filo. Sì, sembra una delle "soluzioni di autenticazione personalizzate", ma in realtà non è perché puoi imporre le regole che desideri sulla password token, come usare un token di firma come password associata alla sessione o ricalcolata su ogni richiesta (senza la condivisione di alcun segreto) in modo che il server possa convalidare il messaggio - quali sono i tuoi bisogni. l'idea è di inviare il token di convalida come "password" della richiesta di autenticazione di base HTTP e non fare affidamento su protocolli più complicati, senza escludere quelli (a tua scelta).


Si potrebbe considerare JWT (Token Web JSON) vedere la bozza JWT rfc . Sicuramente soddisferà i requisiti di sicurezza e di scadenza delle sessioni. Tuttavia, essendo una bozza di standard è improbabile che venga ampiamente utilizzata in questo momento, questo potrebbe cambiare presto da quando JWT fa parte di OAuth 2.0. Le JWT sono facili da implementare nella maggior parte delle lingue e ci sono già molte librerie. Come semplice spiegazione, un token JWT consiste di 3 parti, l'intestazione, il corpo e la firma. L'intestazione e il corpo sono oggetti json che sono codificati in basee64url (gli alfabeti differiscono dalla base64 in base agli ultimi 2 caratteri) e quindi firmati con HMAC256 (o un altro algoritmo specificato nell'intestazione) la RFC spiega come generare esattamente questa firma. Potresti voler controllare questo generatore di token online .

I JWT sono intestazioni http e parametri di query amichevoli.


Ho implementato e rilasciato come open source un servizio di base che consente l'autenticazione, può essere facilmente modificato per consentire l'accesso a 3 tuple se necessario. Ha circa 2 anni e scritto in Java durante la primavera, quindi potresti voler riconsiderare la tecnologia, ma funziona e puoi avere l'idea di base su come è stata realizzata. Trovalo qui su google o segui i post del mio blog su di esso. Si noti che l'app non carica più su cloudbees ma se lo si imposta sul proprio account tutto dovrebbe essere ok.


Una delle buone opzioni da considerare è 'Autenticazione chiave condivisa'. Questo è il tipo di autenticazione utilizzato dal servizio Web di Amazon e dal servizio di archiviazione di Windows Azure. Abbiamo utilizzato l'autenticazione a chiave condivisa nel servizio REST che abbiamo sviluppato. Puoi eseguire una ricerca rapida in "Autenticazione a chiave condivisa" di Google per ottenere molti dettagli.

Ho scritto un post sul blog here su questo.

I passaggi di alto livello sono:

  1. Il client combina un insieme di dati (elementi) univoci definiti dal servizio REST.
  2. Firma questi dati combinati utilizzando una chiave nota solo al servizio client e REST
  3. Invia questa firma al servizio REST come valore per HTTP Header
  4. Il servizio REST calcola la firma esattamente allo stesso modo del client
  5. Confronta la firma inviata dal client con quella calcolata, se la stessa presuppone che sia una richiesta valida respinga la richiesta

Prova a mettere i tuoi dati in un file, ad esempio body.json e quindi a utilizzarli

curl -H "Content-Type: application/json" --data @body.json http://localhost:8080/ui/webapp/conf






web-services rest authentication oauth openid