Qual è il flusso OAuth 2.0 giusto per un'app mobile


87

Sto cercando di implementare l'autorizzazione delegata in un'API Web per app mobili utilizzando OAuth 2.0. Secondo le specifiche, il flusso di concessione implicita non supporta i token di aggiornamento, il che significa che una volta che un token di accesso viene concesso per un periodo di tempo specifico, l'utente deve concedere nuovamente le autorizzazioni all'app una volta che il token scade o viene revocato.

Immagino che questo sia un buon scenario per un po 'di codice javascript in esecuzione su un browser come menzionato nelle specifiche. Sto cercando di ridurre al minimo i tempi in cui l'utente deve concedere le autorizzazioni all'app per ottenere un token, quindi sembra che il flusso del codice di autorizzazione sia una buona opzione in quanto supporta i token di aggiornamento.

Tuttavia, questo flusso sembra fare molto affidamento su un browser Web per eseguire i reindirizzamenti. Mi chiedo se questo flusso sia ancora una buona opzione per un'app mobile se viene utilizzato un browser Web incorporato. O dovrei seguire il flusso implicito?


1
La domanda sarebbe: è come la priorità più alta che l'utente non deve mai digitare di nuovo una password dopo il primo accesso?
leastprivilege

Sì, questo è esattamente il mio requisito. L'utente deve digitare la password solo una volta. Tuttavia, non voglio impostare un token con durata infinita e mantenerlo nell'app mobile, poiché ciò andrebbe contro la possibilità di revocare il token. (A meno che non aggiungo una logica nell'app mobile per rilevare che la richiesta non era autorizzata, quindi chiedo un nuovo token dopo)
Pablo Cibraro

1
Puoi aggiungere un token con durata infinita e comunque revocarlo. E sì, la logica dell'app dovrebbe essere in grado di rilevarlo. RFC 6750 definisce un modo per verificare se l'errore è dovuto a un token revocato.
Pedro Felix

1
Evita le visualizzazioni web (a meno che tu non possieda l'intero stack e non utilizzi l'accesso social) che aprono la possibilità di compromettere le password. Quando mi vengono richieste le credenziali da un agente utente incorporato di terze parti, disinstallo l'app. Alcune API ora vietano persino integrazioni come questa dev.fitbit.com/docs/oauth2 Ho fornito un'altra risposta per chiarire ulteriormente alcuni di questi concetti ( stackoverflow.com/a/38582630/752167 )
Matt C

Risposte:


90

Chiarimento: app mobile = app nativa

Come affermato in altri commenti e in alcune fonti online, l'implicito sembra una scelta naturale per le app mobili, tuttavia la soluzione migliore non è sempre chiara (e in effetti implicita non è raccomandata per i motivi discussi di seguito).

Best practice per OAuth2 dell'app nativa

Qualunque sia l'approccio scelto (ci sono alcuni compromessi da considerare), dovresti prestare attenzione alle migliori pratiche come delineato qui per le app native che utilizzano OAuth2: https://tools.ietf.org/html/rfc8252

Considera le seguenti opzioni

Implicito

Dovrei usare implicit?

Per citare dalla Sezione 8.2 https://tools.ietf.org/html/rfc8252#section-8.2

Il flusso di autorizzazione di concessione implicita OAuth 2.0 (definito nella sezione 4.2 di OAuth 2.0 [RFC6749]) generalmente funziona con la pratica di eseguire la richiesta di autorizzazione nel browser e ricevere la risposta di autorizzazione tramite comunicazione inter-app basata su URI.
Tuttavia, poiché il flusso implicito non può essere protetto da PKCE [RFC7636] (richiesto nella sezione 8.1), l'uso del flusso implicito con app native NON È RACCOMANDATO .

Anche i token di accesso concessi tramite il flusso implicito non possono essere aggiornati senza l'interazione dell'utente, rendendo il flusso di concessione del codice di autorizzazione, che può emettere token di aggiornamento, l'opzione più pratica per le autorizzazioni delle app native che richiedono l'aggiornamento dei token di accesso.

codice di autorizzazione

Se si utilizza il codice di autorizzazione, un approccio potrebbe essere quello di eseguire il proxy tramite il proprio componente del server Web che arricchisce le richieste di token con il segreto del client per evitare di memorizzarlo sull'app distribuita sui dispositivi.

Estratto di seguito da: https://dev.fitbit.com/docs/oauth2/

Il flusso di concessione del codice di autorizzazione è consigliato per le applicazioni che dispongono di un servizio Web. Questo flusso richiede la comunicazione da server a server utilizzando il segreto client di un'applicazione.

Nota: non inserire mai il segreto client nel codice distribuito, come le app scaricate tramite un app store o JavaScript lato client.

Le applicazioni che non dispongono di un servizio Web devono utilizzare il flusso di concessione implicita.

Conclusione

La decisione finale dovrebbe tenere conto della tua esperienza utente desiderata ma anche della tua propensione al rischio dopo aver effettuato un'adeguata valutazione del rischio degli approcci selezionati e una migliore comprensione delle implicazioni.

Un'ottima lettura è qui https://auth0.com/blog/oauth-2-best-practices-for-native-apps/

Un altro è https://www.oauth.com/oauth2-servers/oauth-native-apps/ che afferma

L'attuale best practice del settore consiste nell'utilizzare il flusso di autorizzazione omettendo il segreto del client e utilizzare un agente utente esterno per completare il flusso. Un agente utente esterno è in genere il browser nativo del dispositivo (con un dominio di sicurezza separato dall'app nativa) in modo che l'app non possa accedere all'archivio dei cookie o ispezionare o modificare il contenuto della pagina all'interno del browser.

Considerazione PKCE

Dovresti anche considerare PKCE che è descritto qui https://www.oauth.com/oauth2-servers/pkce/

In particolare, se stai implementando anche il server di autorizzazione, https://www.oauth.com/oauth2-servers/oauth-native-apps/checklist-server-support-native-apps/ afferma che dovresti

  • Consenti ai client di registrare schemi URL personalizzati per i loro URL di reindirizzamento.
  • Supporta URL di reindirizzamento IP di loopback con numeri di porta arbitrari per supportare le app desktop.
  • Non dare per scontato che le app native possano mantenere un segreto. Richiedi a tutte le app di dichiarare se sono pubbliche o riservate e rilascia i segreti del client solo alle app riservate.
  • Supportare l'estensione PKCE e richiedere che i client pubblici la utilizzino.
  • Tenta di rilevare quando l'interfaccia di autorizzazione è incorporata nella visualizzazione Web di un'app nativa, invece di essere avviata in un browser di sistema, e rifiuta tali richieste.

Considerazione sulle visualizzazioni web

Ci sono molti esempi in natura che utilizzano le visualizzazioni Web, ad esempio un agente utente incorporato, ma questo approccio dovrebbe essere evitato (specialmente quando l'app non è di prima parte) e in alcuni casi potrebbe essere vietato l'utilizzo di un'API come estratto sotto da qui dimostra

Qualsiasi tentativo di incorporare la pagina di autenticazione OAuth 2.0 comporterà il divieto della tua applicazione dall'API Fitbit.

Per motivi di sicurezza, la pagina di autorizzazione OAuth 2.0 deve essere presentata in una vista browser dedicata. Gli utenti Fitbit possono confermare che si stanno autenticando con il sito Fitbit.com autentico solo se dispongono degli strumenti forniti dal browser, come la barra degli URL e le informazioni sul certificato Transport Layer Security (TLS).

Per le applicazioni native, ciò significa che la pagina di autorizzazione deve essere aperta nel browser predefinito. Le applicazioni native possono utilizzare schemi URL personalizzati come URI di reindirizzamento per reindirizzare l'utente dal browser all'applicazione che richiede l'autorizzazione.

Le applicazioni iOS possono utilizzare la classe SFSafariViewController invece del passaggio dell'app a Safari. L'uso della classe WKWebView o UIWebView è vietato.

Le applicazioni Android possono utilizzare le schede personalizzate di Chrome invece del passaggio delle app al browser predefinito. L'uso di WebView è vietato.

Per chiarire ulteriormente, ecco una citazione da questa sezione di una precedente bozza del collegamento alle migliori pratiche fornito sopra

Gli user-agent incorporati, comunemente implementati con le visualizzazioni Web, sono un metodo alternativo per autorizzare le app native. Tuttavia, per definizione non sono sicuri per l'uso da parte di terzi. Coinvolgono l'utente che accede con le proprie credenziali di accesso complete, solo per ridurli a credenziali OAuth meno potenti.

Anche se utilizzati da app affidabili di prima parte, gli user-agent incorporati violano il principio del privilegio minimo ottenendo credenziali più potenti di quelle necessarie, aumentando potenzialmente la superficie di attacco.

Nelle tipiche implementazioni basate sulla visualizzazione Web di agenti utente incorporati, l'applicazione host può: registrare ogni battitura immessa nel modulo per acquisire nomi utente e password; invia automaticamente i moduli e ignora il consenso dell'utente; copiare i cookie di sessione e utilizzarli per eseguire azioni autenticate come utente.

Incoraggiare gli utenti a inserire le credenziali in una visualizzazione Web incorporata senza la solita barra degli indirizzi e altre caratteristiche di identità dei browser rende impossibile per l'utente sapere se stanno accedendo al sito legittimo e, anche quando lo sono, li addestra che va bene inserire le credenziali senza prima convalidare il sito.

A parte i problemi di sicurezza, le visualizzazioni Web non condividono lo stato di autenticazione con altre app o il browser di sistema, richiedendo all'utente di accedere per ogni richiesta di autorizzazione e portando a un'esperienza utente scadente.

Per quanto sopra, l'uso di user-agent incorporati NON È RACCOMANDATO, tranne quando un'app di prima parte affidabile funge da agente utente esterno per altre app o fornisce Single Sign-On per più app di prima parte.

I server di autorizzazione DOVREBBERO prendere in considerazione l'adozione di misure per rilevare e bloccare gli accessi tramite agenti utente incorporati che non sono i propri, ove possibile.

Alcuni punti interessanti vengono sollevati anche qui: /security/179756/why-are-developers-using-embedded-user-agents-for-3rd-party-auth-what-are-the- un


3
Google rimuoverà il supporto per le visualizzazioni web il 20 aprile 2017 developers.googleblog.com/2016/08/…
Matt C

Cordiali saluti, il documento fa riferimento all'inizio di questa risposta se non è più bozza OAuth 2.0 per app native - tools.ietf.org/html/rfc8252
Kostiantyn Sokolinskyi

Grazie @KostiantynSokolinskyi, modificato di conseguenza con il link per rfc che non è più bozza
Matt C

@MattC Qual è il modo migliore per implementare la registrazione di un nuovo utente? Dovremmo farlo all'interno dell'app o sull'IDP? È possibile effettuare il login automatico alla registrazione del post dell'utente? stackoverflow.com/questions/60187173/...
Yashvit

Scusa sono confuso su alcuni dettagli ... Potresti dare un'occhiata? Grazie! Link ---> stackoverflow.com/q/61313694/4619958
ch271828n

25

Sfortunatamente, non credo che ci sia una risposta chiara a questa domanda. Tuttavia, ecco le opzioni che ho identificato:

  • Se è consentito chiedere all'utente le proprie credenziali, utilizzare le credenziali della password del proprietario della risorsa . Tuttavia, questo potrebbe non essere possibile per alcuni motivi, vale a dire

    • Le politiche di usabilità o sicurezza vietano l'inserimento della password direttamente nell'app
    • Il processo di autenticazione è delegato a un provider di identità esterno e deve essere eseguito tramite un flusso basato su reindirizzamento HTTP (ad esempio OpenID, SAMLP o WS-Federation)
  • Se è richiesto l'utilizzo di un flusso basato su browser, utilizzare il flusso del codice di autorizzazione . Qui, la definizione di redirect_uriè una sfida importante, per la quale ci sono le seguenti opzioni:

    • Utilizza la tecnica descritta in https://developers.google.com/accounts/docs/OAuth2InstalledApp , dove uno speciale redirect_uri(ad es. urn:ietf:wg:oauth:2.0:oob) Segnala all'endpoint di autorizzazione di mostrare il codice di autorizzazione invece di reindirizzarlo all'app client. L'utente può copiare manualmente questo codice oppure l'app può tentare di ottenerlo dal titolo del documento HTML.
    • Utilizzare un localhostserver sul dispositivo (la gestione delle porte potrebbe non essere facile).
    • Utilizzare uno schema URI personalizzato (ad es. myapp://...) Che quando viene annullato il riferimento attiva un "gestore" registrato (i dettagli dipendono dalla piattaforma mobile).
    • Se disponibile, utilizzare una speciale "visualizzazione web", come WebAuthenticationBroker su Windows 8, per controllare e accedere alle risposte di reindirizzamento HTTP.

Spero che sia di aiuto

Pedro


Grazie Pedro per il contributo !. Sì, sembra che il flusso del codice di autorizzazione con lo schema URI personalizzato o la visualizzazione Web sembra essere l'opzione migliore qui.
Pablo Cibraro

1
Tutto dipende se si desidera che il client digiti la password in una visualizzazione Web o nell'app client. Se possibile, preferirei l'app client, quindi scambiare immediatamente il segreto con un token di accesso / aggiornamento.
leastprivilege

Grazie Dominick !. Il mio cliente utilizza ADFS per autenticare gli utenti, quindi desidera immettere le credenziali nella pagina di accesso. La visualizzazione Web funzionerà per loro
Pablo Cibraro

5
Sono curioso di sapere perché consiglieresti il ​​"flusso del codice di autorizzazione"? Non avresti bisogno di client_secret e client_id per scambiare il codice con un access_token? Ho pensato che il flusso "implicito" fosse progettato per questi scenari, perché non richiede la memorizzazione di segreti nel dispositivo.
Eugenio Pace

1
implicit non supporta i token di aggiornamento OOB. Nello scenario di Pablo, consiglierei chiaramente il flusso RO. Sembra che la società abbia distribuito app sullo stesso back-end dell'azienda.
leastprivilege

9

TL; DR: utilizzare la concessione del codice di autorizzazione con PKCE

1. Tipo di sovvenzione implicita

Il tipo di concessione implicita è molto popolare tra le app mobili. Ma non doveva essere usato in questo modo. Esistono problemi di sicurezza relativi al reindirizzamento. Justin Richer afferma :

Il problema sorge quando ci si rende conto che, a differenza dell'URL di un server remoto, non esiste un modo affidabile per garantire che l'associazione tra un determinato URI di reindirizzamento e una specifica applicazione mobile sia rispettata. Qualsiasi app sul dispositivo può provare a inserirsi nel processo di reindirizzamento e fare in modo che serva l'URI di reindirizzamento. E indovina un po ': se hai utilizzato il flusso implicito nella tua applicazione nativa, hai semplicemente consegnato all'autore dell'attacco il tuo token di accesso. Non c'è recupero da quel punto: hanno il token e possono usarlo.

E insieme al fatto che non ti consente di aggiornare il token di accesso, meglio evitarlo.

2. Tipo di concessione del codice di autorizzazione

La concessione del codice di autorizzazione richiede un segreto client. Ma non dovresti memorizzare informazioni sensibili nel codice sorgente della tua app mobile. Le persone possono estrarli. Per non esporre il segreto del client, devi eseguire un server come intermediario mentre Facebook scrive :

Consigliamo di utilizzare i token di accesso alle app solo direttamente dai server della tua app per garantire la massima sicurezza. Per le app native, suggeriamo che l'app comunichi con il tuo server e il server quindi effettui le richieste API a Facebook utilizzando il token di accesso all'app.

Non è una soluzione ideale, ma c'è una nuova, un modo migliore per eseguire OAuth sui dispositivi mobili: chiave di prova per lo scambio di codice

3. Tipo di concessione del codice di autorizzazione con PKCE (chiave di prova per scambio di codice)

Fuori dai limiti, è stata creata una nuova tecnica che consente di utilizzare il codice di autorizzazione senza un segreto client. Puoi leggere l'intera RFC 7636 o questa breve introduzione .

PKCE (RFC 7636) è una tecnica per proteggere i client pubblici che non utilizzano un segreto client.

Viene utilizzato principalmente da app native e mobili, ma la tecnica può essere applicata anche a qualsiasi client pubblico. Richiede supporto aggiuntivo da parte del server di autorizzazione, quindi è supportato solo su alcuni provider.

da https://oauth.net/2/pkce/


-3

L'utilizzo di una visualizzazione Web nella tua applicazione mobile dovrebbe essere un modo conveniente per implementare il protocollo OAuth2.0 sulla piattaforma Android.

Per quanto riguarda il campo redirect_uri, penso che http://localhostsia una buona scelta e non devi portare un server HTTP all'interno della tua applicazione, perché puoi sovrascrivere l'implementazione della onPageStartedfunzione nella WebViewClientclasse e interrompere il caricamento della pagina web http://localhostdopo aver controllato il urlparametro.

public void onPageStarted(final WebView webView, final String url,
        final Bitmap favicon) {}

3
Best practice per le app native che utilizzano OAuth2: tools.ietf.org/html/draft-wdenniss-oauth-native-apps
Matt C

1
Come ha detto Matt C, sopra. Le visualizzazioni Web sono una cattiva idea per le app mobili: non sono sicure, consentono all'app di accedere alle credenziali (quindi non più sicure di RO) e non consentono agli utenti di verificare i certificati di dominio e TLS. Utilizza il tipo di concessione del codice di autenticazione con un gestore URI personalizzato e assicurati di utilizzare il codice di prova per lo scambio di chiavi (PKCE) per impedire alle app dannose sul telefono di intercettare il codice di autenticazione e ottenere l'accesso alla tua API.
ChrisC

2
La versione aggiornata della bozza del documento sulle best practice OAuth 2.0 per le app native si trova su tools.ietf.org/html/draft-ietf-oauth-native-apps
Jeff Olson,

-4

L'esperienza utente più fluida per l'autenticazione e la più semplice da implementare è incorporare una visualizzazione Web nella tua app. Elaborare le risposte ricevute dal webview dal punto di autenticazione e rilevare l'errore (annullamento dell'utente) o l'approvazione (ed estrarre il token dai parametri di query dell'URL). E penso che tu possa effettivamente farlo su tutte le piattaforme. Ho funzionato con successo per quanto segue: ios, android, mac, app di Windows Store 8.1, app di Windows Phone 8.1. L'ho fatto per i seguenti servizi: dropbox, google drive, onedrive, box, basecamp. Per le piattaforme non Windows, stavo usando Xamarin che presumibilmente non espone le API specifiche dell'intera piattaforma, ma ha esposto abbastanza per renderlo possibile. Quindi è una soluzione abbastanza accessibile, anche da una prospettiva multipiattaforma, e non


Pur fornendo una comoda esperienza utente, vedremo il settore allontanarsi da questo approccio. Poiché le visualizzazioni Web aprono la possibilità di compromettere le password, quando mi vengono richieste le credenziali da un agente utente incorporato, disinstallo l'app. Alcune API ora vietano persino integrazioni come questa dev.fitbit.com/docs/oauth2
Matt C

Best practice per le app native che utilizzano OAuth2: tools.ietf.org/html/draft-wdenniss-oauth-native-apps
Matt C

Non vedo come potrebbe un servizio abilitato oauth vietare questo approccio. Non è rilevabile e sicuro ... Alcuni servizi abilitati oauth forniscono client specifici della piattaforma per facilitare l'autenticazione, e tali client in realtà fanno ciò che ho descritto qui (mostra una visualizzazione web incorporata e tiene traccia delle modifiche all'URL). La migliore pratica che hai collegato, consiglia la stessa cosa: usa il browser di sistema o la visualizzazione web incorporata. Quale argomento stai attaccando dalla mia risposta? non è chiaro.
Radu Simionescu

Nessun attacco previsto, solo evidenziando il problema. Il collegamento dice che ci sono i 2 approcci che hai menzionato, ma solo uno user-agent esterno può essere considerato sicuro, in particolare dice che le opzioni per le app native sono "tramite uno user-agent incorporato o un user-agent esterno. Questo documento consiglia gli user-agent come le schede del browser in-app come unica scelta sicura e utilizzabile per OAuth ".
Matt C

Ulteriore citazione "Nelle tipiche implementazioni basate sulla visualizzazione web di agenti utente incorporati, l'applicazione host può: registrare ogni battitura inserita nel modulo per acquisire nomi utente e password; inviare automaticamente moduli e bypassare il consenso dell'utente" ....... "l'uso di user-agent incorporati NON È RACCOMANDATO, tranne quando un'app di prima parte affidabile funge da agente utente esterno per altre app o fornisce Single Sign-On per più app di prima parte. I server di autorizzazione DOVREBBERO prendere in considerazione l'adozione di misure per rilevare e bloccare gli accessi tramite user-agent incorporati che non sono i propri, ove possibile. "
Matt C
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.