Autenticazione API REST


181

Sto creando un'applicazione che sarà ospitata su un server. Voglio creare un'API per l'applicazione per facilitare l'interazione con da qualsiasi piattaforma (app Web, app mobile). Quello che non capisco è che quando si utilizza l'API REST, come si autentica l'utente.

Ad esempio, quando un utente ha effettuato l'accesso e desidera creare un argomento del forum. Come faccio a sapere che l'utente è già connesso?


4
Probabilmente dovresti cercare "Autenticazione REST" qui. È stato trattato in molte altre domande.
Brian Kelly,

10
In poche parole, lascia che il client invii un nome utente e una password per ogni richiesta utilizzando HTTP Basic Auth (su SSL!) O esegua l'autenticazione una volta in modo che il client abbia una sessione autenticata che scadrà dopo un certo periodo di inattività (o comunque scegli di sovrascrivere la gestione della sessione del tuo web framework). Tale sessione può quindi essere memorizzata in un cookie o essere un parametro passato ad ogni richiesta (es. JSESSIONID in Java land).
opyate


@opyate dal punto di vista della sicurezza, non è davvero una buona idea gestire la sessione utilizzando i cookie in un caso API REST, poiché gli aggressori possono inviare richieste senza il consenso dell'utente. È meglio includere un hash o un token di sessione in un'intestazione HTTP (ad esempio Autorizzazione).
s3v3n,

1
@ s3v3n Correggimi se sbaglio, ma sia il tuo che i miei suggerimenti sono solo modi diversi di utilizzare un'intestazione + una combinazione di archiviazione locale per effettuare la stessa cosa. È Authorizationheader + ad es. Browser localStorage VS Cookieheader + archiviazione standard dei cookie del browser.
opyate

Risposte:


72

È possibile utilizzare l'autenticazione HTTP di base o digest. Puoi autenticare in modo sicuro gli utenti utilizzando SSL nella parte superiore, tuttavia, rallenta un po 'l'API.

  • Autenticazione di base: utilizza la codifica Base64 su nome utente e password
  • Autenticazione digest: esegue l'hashing del nome utente e della password prima di inviarli sulla rete.

OAuth è il meglio che può ottenere. I vantaggi offerti da oAuth sono token revocabili o prevedibili. Fare riferimento a seguito su come implementare: Link di lavoro dai commenti: https://www.ida.liu.se/~TDP024/labs/hmacarticle.pdf


4
Si prega di leggere questa domanda e la risposta fornita da Les Hazelwood (autore di Apache Shiro).
justin.hughey,

1
Link utile su come protegge l'API REST di Twitter
WildDev,

Poiché questa è la risposta accettata, ritengo sia importante menzionare che è possibile utilizzare anche l'autenticazione Digest. Leggi le differenze tra Basic e Digest autenticazioni qui: stackoverflow.com/questions/9534602/...
rayée Roded

116

Ad esempio, quando un utente ha il login. Ora diciamo che l'utente desidera creare un argomento del forum, come faccio a sapere che l'utente ha già effettuato l'accesso?

Pensaci: ci deve essere una stretta di mano che dice all'API "Crea forum" che questa richiesta corrente proviene da un utente autenticato. Poiché le API REST sono in genere senza stato, lo stato deve essere persistente da qualche parte . Il client che utilizza le API REST è responsabile del mantenimento di tale stato. Di solito, è sotto forma di token che viene passato dal momento in cui l'utente ha effettuato l'accesso. Se il token è valido, la richiesta è buona.

Controlla come Amazon AWS esegue le autenticazioni. Questo è un esempio perfetto di "passare il dollaro" da un'API all'altra.

* Ho pensato di aggiungere una risposta pratica alla mia risposta precedente. Prova Apache Shiro (o qualsiasi libreria di autenticazione / autorizzazione). In conclusione, cerca di evitare la codifica personalizzata. Dopo aver integrato la tua libreria preferita (io uso Apache Shiro, a proposito) puoi quindi fare quanto segue:

  1. Creare un'API di accesso / disconnessione come: /api/v1/logineapi/v1/logout
  2. In queste API di accesso e disconnessione, eseguire l'autenticazione con l'archivio utenti
  3. Il risultato è un token (di solito JSESSIONID) che viene inviato al client (web, mobile, qualunque cosa)
  4. Da questo punto in poi, tutte le successive chiamate effettuate dal cliente includeranno questo token
  5. Supponiamo che la tua prossima chiamata venga effettuata a un'API chiamata /api/v1/findUser
  6. La prima cosa che farà questo codice API è verificare il token ("questo utente è autenticato?")
  7. Se la risposta torna come NO, si restituisce uno stato HTTP 401 al client. Lascia che lo gestiscano.
  8. Se la risposta è SÌ, procedere con la restituzione dell'utente richiesto

È tutto. Spero che questo ti aiuti.


Quindi quello che stai descrivendo è essenzialmente un cookie di sessione, giusto?
LordOfThePigs

si, ma la sessione è "mantenuta" in 2 posti diversi. Uno nel server API, un altro nel browser. La risposta JSON (o qualsiasi altra cosa) al login post corretto del browser dovrebbe comunicare al browser l'ID sessione sul server API. Queste sessioni sono gestite in modo indipendente dai rispettivi agenti.
Kingz,

11
Credo che Kingz stesse cercando di comunicare l'idea che il meccanismo per mantenere la sessione è intenzionalmente vago. Un cookie di sessione è solo un'implementazione di quel meccanismo.
justin.hughey,

2
@Kingz, che dire della sicurezza in questa soluzione, ad esempio se qualche hacker annusa il collegamento con session_id e inizia a inviare richieste con il contenuto corretto session_id? Possiamo risolverlo aggiungendo ssl alla connessione al server, ma per quanto riguarda i client?
Ahmad Samilo,

1
come prevenire il dirottamento di sessione nel caso man-in-the-middle-attrack?
m0z4rt,

38
  1. Utilizzare HTTP Basic Auth per autenticare i client, ma trattare username / password solo come token di sessione temporaneo .

    Il token di sessione è solo un'intestazione collegata a ogni richiesta HTTP, ad esempio: Authorization: Basic Ym9ic2Vzc2lvbjE6czNjcmV0

    La stringa Ym9ic2Vzc2lvbjE6czNjcmV0 sopra è solo la stringa "bobsession1: s3cret" (che è un nome utente / password) codificata in Base64.

  2. Per ottenere il token di sessione temporanea sopra riportato, fornire una funzione API (ad esempio:) http://mycompany.com/apiv1/loginche accetta come input un nome utente master e una password master, crea un nome utente / password Auth di base HTTP temporaneo sul lato server e restituisce il token (ad esempio: Ym9ic2Vzc2lvbjE6czNjcmV0). Questo nome utente / password dovrebbe essere temporaneo, dovrebbe scadere dopo circa 20 minuti.

  3. Per una maggiore sicurezza, assicurati che il tuo servizio REST sia servito su HTTPS in modo che le informazioni non vengano trasferite in chiaro

Se sei su Java, la libreria Spring Security offre un buon supporto per implementare il metodo sopra


1
Perché dovrebbe scadere dopo 20 minuti? cosa succede se è un sito web come Facebook che il login è fino a quando l'utente non si disconnette?
Dejell,

1
@dejel Ero convinto che la "sessione" fosse di natura temporanea. È
normale

A cosa serve la Base64? Potresti semplicemente restituire la password temporanea. In entrambi i casi, ciò che conta davvero è che questa password temporanea è forte. Controlla security.stackexchange.com/a/19686/72945
e18r

7

Penso che l'approccio migliore sia usare OAuth2. Cercalo su Google e troverai molti post utili per aiutarti a configurarlo.

Semplifica lo sviluppo di applicazioni client per la tua API da un'app Web o mobile.

Spero che ti aiuti.


2
Si prega di leggere questa domanda e la risposta di Les Hazelwood (autore di Apache Shiro).
justin.hughey,

0

Sto usando l'autenticazione JWT. Funziona bene nella mia applicazione.

Esiste un metodo di autenticazione che richiederà le credenziali dell'utente. Questo metodo convalida le credenziali e restituisce un token di accesso in caso di successo.

Questo token deve essere inviato ad ogni altro metodo nella mia API Web nell'intestazione della richiesta.

È abbastanza facile da implementare e molto facile da testare.

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.