OAuth2 ROPC vs Auth di base per le API REST pubbliche?


21

Il caso d'uso specifico che mi interessa qui è l'autenticazione dei client REST rispetto agli endpoint del server disponibili pubblicamente (come un'API REST pubblica).

La soluzione più semplice qui è l' autent di base . Ma sento spesso OAuth2 pubblicizzato come una soluzione di autenticazione superiore in quasi tutte le circostanze.

Il fatto è che l' unico tipo di concessione OAuth2 possibile per un client REST che esegue l'autenticazione su un server REST è Credenziali password proprietario risorse (ROPC) , poiché le concessioni di codice e le sovvenzioni implicite richiedono un'interfaccia utente / pagina Web (ospitata dal server di autenticazione) per il utente per accedere e autorizzare manualmente l'app client.

Il modo in cui funziona ROPC è, inviando il nome utente / password del proprietario della risorsa e l'ID client come parametri della stringa di query ?!? Questo è ancora meno sicuro (IMHO) di Basic Auth, che almeno base-64 codifica le credenziali e le invia all'interno di un'intestazione che può essere crittografata da TLS!

Quindi chiedo: nel contesto delle API REST pubbliche, OAuth2 ROPC è davvero migliore di Basic Auth? Cosa è più sicuro di OAuth2 ROPC?


Aggiornare

Ho appena letto questo eccellente articolo che spiega la sicurezza REST non basata su OAuth2 di Amazon per AWS. Si tratta essenzialmente di una soluzione basata su chiave privata in cui gli hash di ciascuna richiesta REST vengono generati e inviati come sidecar insieme alla normale richiesta (non crittografata). Solo il client e il server conoscono la chiave privata, quindi quando il server riceve la richiesta (di nuovo, contenente la richiesta normale + la richiesta con hash), il server cerca la chiave privata del client, applica lo stesso hash alla richiesta normale e quindi confronta i due hash.

Sembra molto più complicato, complesso e sicuro del ROPC di OAuth2! A meno che non mi manca qualcosa importante qui, OAuth2 ROPC è solo l'invio client_id, usernamee passwordcome params stringa di query ... totalmente e assolutamente non protetta! Questa soluzione basata su HMAC / hash sembra essere molto più impressionante e sicura.

Il fatto è che anche l'autore di quell'articolo continua dicendo:

Ti renderai anche lentamente conto e accetti che a un certo punto dovrai implementare OAuth ...

Ba-ba-bwhat?!?! Se OAuth2 è meno sicuro di questa intelligente soluzione basata su HMAC / hash, perché l'autore di questo articolo ritiene che OAuth debba essere abbracciato ad un certo punto. Sono così confuso.


Di che tipo di cliente stai parlando? Presumo che la maggior parte dei client avrà un'interfaccia utente. In tal caso, è possibile caricare la pagina di accesso OAuth in una visualizzazione Web (desktop, dispositivo mobile) o reindirizzare ad essa direttamente (Web). Non vedo perché è necessario evitare l'interfaccia utente.
deciclone,

@decyclone, leggi la prima frase alla domanda! Sto prendendo in considerazione i client REST (HTTP senza testa) che eseguono l'autenticazione rispetto ai servizi REST.
smeeb,

La domanda che sto ponendo è se quel client ha un'interfaccia utente? Anche se non fosse così, ho visto applicazioni senza interfaccia utente aprire una finestra di dialogo almeno per l'autenticazione.
deciclone,

@decyclone no un client REST puro non ha alcuna UI, sebbene in genere l'interfaccia utente utilizzi un client REST puro per la connessione a un servizio REST. Un caso d'uso è uno strumento da riga di comando che utilizza un client REST per inviare comandi utente (immessi sulla shell) al servizio REST. Interrompere un'interfaccia utente da una shell non è una soluzione accettabile qui.
smeeb,

1
Ma, dovrei notare, ci sono molti altri casi d'uso al di fuori di una riga di comando / shell. Un altro caso d'uso è un client REST / HTTP puro Java / Ruby / Python che non ha UI e potrebbe essere in esecuzione su un server back-end che non ha UI. Il server back-end deve comunicare con un altro server back-end tramite REST. Qui, non solo sarebbe imbarazzante e scomodo far apparire un'interfaccia utente quando il server back-end n. 1 deve parlare con il server back-end n. 2, il vero problema è che non esiste un browser / client dell'interfaccia utente in cui visualizzare la pagina di accesso e non esiste alcun essere umano essere lì per accedere !!!
smeeb,

Risposte:


24

La risposta alla tua domanda può essere a livello di codice, a livello di protocollo o a livello di architettura. Cercherò di sintetizzare qui la maggior parte dei problemi a livello di protocollo poiché ciò è di solito fondamentale nell'analisi dei pro e dei contro. Tieni presente che OAuth2 è molto più delle credenziali della password del proprietario della risorsa che, secondo le specifiche, esistono per "motivi legacy o di migrazione", sono considerate "a rischio più elevato rispetto ad altri tipi di concessione" e la specifica afferma esplicitamente che i client e i server di autorizzazione "DOVREBBE ridurre al minimo l'uso di questo tipo di sovvenzione e utilizzare altri tipi di sovvenzioni quando possibile".

Ci sono ancora molti vantaggi nell'utilizzo di ROPC rispetto all'autenticazione di base, ma prima di approfondire, capiamo la differenza di protocollo di base tra OAuth2 e l'autenticazione di base. Per favore, abbi pazienza mentre spiego questi e arriverà a ROPC più tardi.

Flussi di autenticazione dell'utente

Esistono quattro ruoli definiti nella specifica OAuth2. Con esempi, sono:

  1. Proprietario della risorsa: l'utente che ha accesso ad alcune risorse, ad esempio nel tuo caso, utenti diversi possono avere un livello di accesso diverso all'API REST;
  2. Il client: di solito l'applicazione che l'utente sta utilizzando e necessita dell'accesso alla risorsa per fornire servizi all'utente;
  3. Server di risorse: l'API REST nel tuo caso; e
  4. Server di autorizzazione: il server a cui vengono presentate le credenziali dell'utente e che autentica l'utente.

Quando viene eseguita un'applicazione client, viene concesso l'accesso alle risorse in base all'utente. Se un utente dispone dei privilegi di amministratore, le risorse e le operazioni disponibili per l'utente nell'API REST potrebbero essere molto più di un utente senza privilegi di amministratore.

OAuth2 consente inoltre la possibilità di utilizzare un singolo server di autorizzazione con più client e per più risorse. Ad esempio, un server di risorse può accettare l'autenticazione dell'utente con Facebook (che può fungere da server di autorizzazione in tal caso). Pertanto, quando l'utente esegue un'applicazione (ovvero il client), invia l'utente a Facebook. L'utente digita le proprie credenziali su Facebook e il client riceve un "token" che può presentare al server delle risorse. Il server delle risorse esamina il token e lo accetta dopo aver verificato che Facebook lo ha effettivamente emesso e consente all'utente di accedere alla risorsa. In questo caso, il client non vede mai le credenziali dell'utente (ovvero le credenziali di Facebook).

Supponiamo che tu stia gestendo le identità del tuo utente (e disponga di un server di autorizzazione) invece di Facebook, che garantisce già token al tuo client. Ora, supponiamo che tu abbia anche un partner e desideri consentire alla sua applicazione (client) di accedere all'API REST. Con l'autenticazione di base (o persino ROPC), l'utente fornirà le credenziali a quel client che lo invierà al server di autorizzazione. Il server di autorizzazione fornirà quindi un token che può essere utilizzato dal client per accedere alle risorse. Sfortunatamente, questo significa che le credenziali dell'utente sono ora visibili anche a quel client. Tuttavia, non si desidera che l'applicazione di un partner (che potrebbe essere esterna alla propria organizzazione) sia a conoscenza della password di un utente. Questo è un problema di sicurezza ora. Al fine di raggiungere tale obiettivo,

Pertanto, con OAuth2, idealmente non si userebbe ROPC in tali casi piuttosto che usarne uno diverso, come il flusso del codice di autorizzazione. Ciò protegge qualsiasi applicazione dalla conoscenza delle credenziali dell'utente che vengono presentate solo al server di autorizzazione. Pertanto, le credenziali di un utente non vengono divulgate. Gli stessi problemi si applicano con l'autenticazione di base, ma nella sezione successiva spiegherò come ROPC sia ancora migliore perché le credenziali dell'utente non devono ancora essere archiviate dal client in ROPC per un accesso persistente da parte dei client.

Si noti che quando l'utente accede al server di autorizzazione, il server di autorizzazione può anche chiedere all'utente di confermare che desidera consentire al client di accedere alle risorse per suo conto o meno. Questo è il motivo per cui viene chiamato server di autorizzazione perché il processo di autorizzazione di un client per accedere alle risorse è implicato nel processo. Se l'utente non autorizza il client, non otterrà l'accesso alle risorse. Allo stesso modo, se l'utente stesso non ha accesso alle risorse, il server di autorizzazione può comunque negare l'accesso e non emettere un token.

Nell'autenticazione di base, anche il server delle autorizzazioni e il server delle risorse sono combinati in un'unica entità. Pertanto, il server delle risorse desidera autorizzare l'utente, quindi richiede le credenziali dal client. Il client fornisce le credenziali utilizzate dal server delle risorse per autenticare l'utente. Ciò significa che più server di risorse richiederanno essenzialmente le credenziali dell'utente.

Emissione di token

I client ottengono token dal server di autorizzazione, li tengono in giro e li usano per accedere alle risorse (maggiori dettagli sui token stessi di seguito). I client non conoscono mai la password dell'utente (in flussi diversi da ROPC) e non devono memorizzarla. In ROPC, anche se i client conoscono la password dell'utente, non devono ancora memorizzarla perché utilizzano questi token per accedere alle risorse. Al contrario, nell'autenticazione di base, se un client non desidera che l'utente fornisca le credenziali in ogni sessione, il client deve archiviare la password dell'utente in modo che possa fornirla la volta successiva. Questo è uno svantaggio principale dell'utilizzo dell'autenticazione di base, a meno che il client non sia solo un'applicazione Web, nel qual caso i cookie possono affrontare alcune di queste preoccupazioni. Con le applicazioni native, di solito non è un'opzione.

C'è un altro aspetto di OAuth2 che consiste nel modo in cui i token vengono emessi e funzionano. Quando un utente fornisce le credenziali al server di autorizzazione (anche in ROPC), il server di autorizzazione può fornire uno o più dei due tipi di token: 1) token di accesso e 2) token di aggiornamento.

I token di accesso vengono inviati al server delle risorse che garantirà l'accesso alle risorse dopo la convalida e di solito hanno una durata breve, ad esempio 1 ora. I token di aggiornamento vengono inviati al server delle autorizzazioni dal client per ottenere un altro token di accesso quando scade e di solito hanno una lunga durata (ad esempio da alcuni giorni a mesi o addirittura anni).

Quando il client fornisce il token di accesso al server delle risorse, guarda il token e dopo la convalida, guarda all'interno del token per determinare se consentire o meno l'accesso. Finché il token di accesso è valido, il client può continuare a utilizzarlo. Supponiamo che l'utente chiuda l'applicazione e la avvii il giorno successivo e il token di accesso sia scaduto. Ora il client effettuerà una chiamata al server di autorizzazione e presenterà il token di aggiornamento supponendo che non sia scaduto. Il server di autorizzazione, poiché ha già emesso il token, lo verifica e può determinare che l'utente non deve fornire nuovamente le credenziali e quindi fornisce un altro token di accesso al client. Il client ora ha di nuovo accesso al server delle risorse. Questo è il modo in cui in genere le applicazioni client per Facebook e Twitter richiedono le credenziali una volta e quindi non richiedono all'utente di fornire nuovamente le credenziali. Queste applicazioni non devono mai conoscere le credenziali degli utenti e possono comunque accedere alle risorse ogni volta che l'utente avvia l'applicazione.

Ora l'utente può accedere al server di autorizzazione (ad es. Nel proprio profilo utente di Facebook), modificare la password senza influire sulle applicazioni client. Continueranno tutti a funzionare correttamente. Se l'utente perde un dispositivo sul quale aveva già un'applicazione con token di aggiornamento, può dire al server di autorizzazione (ad esempio Facebook) di "disconnetterlo" da quelle applicazioni che il server di autorizzazione (ad esempio Facebook) realizzerà non onorando alcuna esistente aggiorna i token e costringe l'utente a fornire nuovamente le credenziali quando tenta di accedere alle risorse attraverso tali applicazioni.

JWT è semplicemente il formato token che viene solitamente utilizzato con OAuth2 e OpenID Connect. I metodi per firmare e convalidare il token sono anche standardizzati con librerie disponibili per quelli invece di ogni server di risorse che implementa l'ennesima soluzione. Pertanto, il vantaggio risiede nella riusabilità del codice che è stato verificato e continua a essere supportato.

Implicazioni sulla sicurezza

L'autenticazione di base sarà più debole quando uno degli scenari di cui sopra è nella foto. Esiste anche un ampio modello di minaccia per OAuth2 disponibile per gli sviluppatori che possono utilizzare i suggerimenti in esso contenuti per evitare vulnerabilità comuni nelle loro implementazioni. Se passi attraverso il modello di minaccia, vedrai che sono coperte anche molte vulnerabilità legate all'implementazione (come open redirector e CSRF). In questa risposta non ho analizzato quelli confrontati con l'autenticazione di base.

L'ultimo grande vantaggio di OAuth2 è che il protocollo è standardizzato e più server di autorizzazione, client e server di risorse lo onorano. Numerose librerie sono disponibili per gli sviluppatori, che vengono mantenute in modo che quando vengono rilevati problemi di sicurezza nelle implementazioni, le librerie vengono aggiornate consentendo l'interoperabilità.

Conclusione

Se stai scrivendo una nuova applicazione, IMO, il caso ideale sarebbe quello di evitare sia l'autenticazione di base che il ROPC a causa dei problemi inerenti. Tuttavia, ogni applicazione ha esigenze, tempistiche, competenza degli sviluppatori ecc. Differenti, quindi la decisione viene presa caso per caso. Ma anche se non avessi più bisogno dell'autenticazione di base, scegliendola, potresti bloccarti in un'architettura che potrebbe non essere facile da estendere (ad esempio se in futuro avessi più server, non vorrai necessariamente avere l'utente fornisce le credenziali a ciascuno di essi piuttosto che fornire al server di autorizzazione una volta sola, che può distribuire token, ecc.)

Nota che non ho risposto al tuo commento su come le credenziali vengono inviate via cavo perché possono essere protette utilizzando TLS o un protocollo simile, o prova del possesso ecc. Come qualcuno ha già suggerito, la codifica base 64 è 0 di sicurezza, per favore non farlo essere illuso da quello. Le differenze sopra menzionate sono di solito a livello architettonico e quindi è lì che mi sono concentrato perché l'architettura è la più difficile da cambiare una volta implementata.

Azure Active Directory B2C Basic , un servizio su cui lavoro ed è stato recentemente rilasciato per l'anteprima pubblica, consente all'applicazione di terze parti di utilizzare AAD come server di autorizzazione con interoperabilità con IDP sociali (come Facebook, Google, ecc.). Inoltre, consente agli utenti di creare i propri account anziché utilizzare gli IDP sociali e questi possono essere successivamente utilizzati a fini di autenticazione. Ci sono anche alcuni altri servizi del genere (ad esempio un altro che conosco è auth0) che possono essere utilizzati dagli sviluppatori per esternalizzare completamente l'autenticazione e la gestione degli utenti per le loro applicazioni e risorse. Le stesse caratteristiche dei protocolli che ho menzionato sopra sono utilizzate dagli sviluppatori per disaccoppiare il server di autorizzazione (AAD), una risorsa (ad esempio le loro API REST), il client (ad esempio le loro applicazioni mobili) e gli utenti. Spero che questa spiegazione sia di aiuto.


Grazie per un grandangolo, ma non credo che questi vantaggi (a) letting the user agent hold just the token instead of the password, (b) allowing a password change without disrupting existing client apps, (c) allowing users log out other sessionssiano specifici per i flussi di autenticazione dei token. Né le autenticazioni Basic né token menzionano le funzioni (b) e (c) nelle loro specifiche. L'implementazione di (b) e (c) sembra possibile per qualsiasi tipo di autenticazione. Implicherebbe il monitoraggio delle password (preferibilmente i loro hash). Il vantaggio (a) sembra dipendere dall'ambito più ampio della password.
Eel GhEEz,

Come possiamo usare OAuth se l'utente (proprietario della risorsa) non ha credenziali con un server di autorizzazione esterno, ma ha credenziali nell'applicazione client? Cioè abbiamo il proprietario delle risorse (utente), il client (che rappresenta l'utente e che contiene anche le credenziali per l'utente) e il server delle risorse. Come può un server di risorse autenticare e autorizzare l'utente?
Arun Avanathan,

3

Credo che tu sia male informato sulla crittografia attorno alle variabili GET in un URL

Le uniche persone che possono visualizzare le variabili GET in una richiesta sono il computer originale e il server di ricezione ( collegamento ).

Solo la ricerca DNS basata sul dominio a cui viene inviata la richiesta HTTPS non è crittografata. Tutto il resto, le porte, le variabili GET, l'ID risorsa, sono crittografati.

L'unica avvertenza è che il server ricevente può disconnettere l'intero percorso della richiesta, ma tu ne hai il controllo in modo da poter proteggere quei dati come ritieni opportuno.


3

L'autenticazione di base non è un buon modo per proteggere l'API REST. Ho spiegato i motivi per cui in questa risposta .

Quando si crea un'API REST, si sta implementando il server delle risorse in termini di OAuth2. Tutto ciò che l'API deve fare è confermare che il token passato insieme alla richiesta nell'intestazione HTTP di autorizzazione sia valido e proveniente da un emittente fidato. Vedi questo link per i passaggi su come implementare la validazione se non ci sono librerie disponibili.

Il modo in cui il client acquisisce il token dal server delle autorizzazioni dipende dal tipo di client . Ricorda, devi specificare il tipo di client che intendi utilizzare quando registri il client con il server di autorizzazione.

Nel caso in cui un'applicazione Web parli con il tuo server, potrebbe utilizzare la concessione del codice di autorizzazione . Se si tratta di un client non attendibile come un'applicazione mobile o un'app JavaScript, dovrebbe utilizzare la concessione implicita .

Per i servizi di back-end che non possono interagire con un proprietario di risorse, è possibile utilizzare la concessione delle credenziali del client . Per gli strumenti da riga di comando, è possibile utilizzare le credenziali del client o la concessione della password del proprietario della risorsa .

Tutto dipende dal tipo di client che stai utilizzando.

Infine, la convalida di un token JWT avviene sul server delle risorse senza la necessità di parlare con il server delle autorizzazioni. Ciò porta a una migliore architettura scalabile rispetto alle soluzioni che devono cercare dati privati ​​per ciascun client.


1

È sicuro o non sicuro. Ne più ne meno. Avere base64 non rende l'autent di base (o nulla) più sicuro.

Non c'è nulla di sbagliato nell'invio di qualcosa di non crittografato se utilizza una pipe crittografata come Https.

OAuth ha più funzionalità, usalo se ne hai bisogno. Per qualsiasi altra cosa, ad esempio il settore bancario, l'utilizzo della risposta di sfida di base è corretto e sicuro.


0

Penso che tu debba prima capire le terminologie. Stai confrontando - Autorizzazione e firma digitale

OAuth è uno standard aperto per l' autorizzazione , in cui ciò che Amazon sta facendo (secondo l'articolo e i dettagli forniti nella tua domanda) sta creando una firma digitale valida che fornisce a un destinatario (qui Amazon) un motivo per ritenere che il messaggio sia stato creato da un noto mittente, che il mittente non può negare di aver inviato il messaggio ( autenticazione e non ripudio)

Per quale meccanismo di autorizzazione utilizzare, dipende più o meno dal tuo caso d'uso.

Di seguito è riportato ciò che è possibile trovare su StackOverflow qui :

Autenticazione di base che richiede un hashing molto semplice per calcolare la singola intestazione richiesta: OAuth è senza dubbio un'autenticazione più costosa. La cosa importante da capire è che i due meccanismi di autenticazione hanno scopi completamente diversi. L'autorizzazione di base è per l'autenticazione di un client in un'applicazione primaria. OAuth è per autorizzare una terza parte ad accedere ai dati del client da un'applicazione primaria. Entrambi hanno il loro posto e la selezione l'uno sull'altro dovrebbe essere guidata dal caso d'uso specifico dell'implementazione.

Ed ecco un altro articolo interessante che confronta i due.

L'autenticazione di base su SSL è in realtà abbastanza responsabile, da un punto di vista della sicurezza semplicistico. Quando contendiamo nomi utente e password, l'autent di base è una soluzione prevalente in quanto è così facile da implementare. La trasmissione delle credenziali è crittografata su SSL e l'uso dell'intestazione "Autorizzazione" è onnipresente nei client e nei sistemi HTTP.

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.