Jaki jest właściwy przepływ OAuth 2.0 dla aplikacji mobilnej

87

Próbuję zaimplementować delegowaną autoryzację w internetowym interfejsie API dla aplikacji mobilnych przy użyciu protokołu OAuth 2.0. Zgodnie ze specyfikacją niejawny przepływ uprawnień nie obsługuje tokenów odświeżania, co oznacza, że ​​po przyznaniu tokenu dostępu na określony czas użytkownik musi ponownie udzielić uprawnień aplikacji po wygaśnięciu tokenu lub jego unieważnieniu.

Wydaje mi się, że jest to dobry scenariusz dla jakiegoś kodu javascript działającego w przeglądarce, jak wspomniano w specyfikacji. Próbuję zminimalizować czas, w którym użytkownik musi przyznać uprawnienia aplikacji, aby uzyskać token, więc wygląda na to, że przepływ kodu autoryzacji jest dobrą opcją, ponieważ obsługuje tokeny odświeżania.

Wydaje się jednak, że ten przepływ w dużym stopniu opiera się na przeglądarce internetowej do wykonywania przekierowań. Zastanawiam się, czy ten przepływ jest nadal dobrą opcją dla aplikacji mobilnej, jeśli używana jest wbudowana przeglądarka internetowa. Czy powinienem iść z ukrytym przepływem?

Pablo Cibraro
źródło
1
Pytanie brzmiałoby - czy jest to najwyższy priorytet, aby użytkownik nigdy więcej nie musiał wpisywać hasła po pierwszym zalogowaniu?
najmniejprivilege
Tak, to jest dokładnie moje wymaganie. Użytkownik powinien wpisać hasło tylko raz. Jednak nie chcę konfigurować tokena z nieskończonym okresem istnienia i przechowywać go w aplikacji mobilnej, ponieważ byłoby to sprzeczne z możliwością unieważnienia tokena. (Chyba że dodam jakąś logikę w aplikacji mobilnej, aby wykryć, że żądanie było nieautoryzowane, więc później proszę o nowy token)
Pablo Cibraro
1
Możesz dodać token z nieskończonym okresem ważności i nadal go unieważniać. I tak, logika aplikacji powinna być w stanie to wykryć. RFC 6750 określa sposób sprawdzenia, czy błąd jest spowodowany unieważnionym tokenem.
Pedro Felix
1
Unikaj widoków internetowych (chyba że posiadasz pełny stos i nie korzystasz z logowania społecznościowego), które stwarzają możliwość złamania haseł. Gdy jestem proszony o podanie poświadczeń przez wbudowanego klienta użytkownika innej firmy, odinstalowałbym aplikację. Niektóre interfejsy API nawet zakazują takich integracji, jak ta dev.fitbit.com/docs/oauth2 Podałem inną odpowiedź, aby dokładniej wyjaśnić niektóre z tych koncepcji ( stackoverflow.com/a/38582630/752167 )
Matt C

Odpowiedzi:

90

Wyjaśnienie: aplikacja mobilna = aplikacja natywna

Jak stwierdzono w innych komentarzach i kilku źródłach online, domniemanie wydaje się być naturalnym rozwiązaniem dla aplikacji mobilnych, jednak najlepsze rozwiązanie nie zawsze jest jednoznaczne (i w rzeczywistości nie jest zalecane z powodów omówionych poniżej).

Sprawdzone metody dotyczące aplikacji natywnej OAuth2

Niezależnie od wybranego podejścia (jest kilka kompromisów do rozważenia), należy zwrócić uwagę na najlepsze praktyki opisane tutaj dla aplikacji natywnych korzystających z OAuth2: https://tools.ietf.org/html/rfc8252

Rozważ następujące opcje

Domniemany

Czy powinienem używać ukrytego?

Cytując z sekcji 8.2 https://tools.ietf.org/html/rfc8252#section-8.2

Przepływ niejawnej autoryzacji OAuth 2.0 (zdefiniowany w sekcji 4.2 protokołu OAuth 2.0 [RFC6749]) generalnie działa z praktyką wykonywania żądania autoryzacji w przeglądarce i otrzymywania odpowiedzi autoryzacyjnej poprzez komunikację między aplikacjami opartą na URI.
Ponieważ jednak niejawny przepływ nie może być chroniony przez PKCE [RFC7636] (co jest wymagane w sekcji 8.1), użycie Niejawnego przepływu z aplikacjami natywnymi NIE JEST ZALECANE .

Tokeny dostępu przyznane za pośrednictwem niejawnego przepływu również nie mogą być odświeżane bez interakcji użytkownika, co sprawia, że ​​przepływ przyznawania kodu autoryzacji - który może wydawać tokeny odświeżania - jest bardziej praktyczną opcją dla autoryzacji aplikacji natywnych, które wymagają odświeżenia tokenów dostępu.

Kod autoryzacji

Jeśli zdecydujesz się na kod autoryzacji, jednym ze sposobów byłoby proxy za pośrednictwem własnego komponentu serwera internetowego, który wzbogaca żądania tokenu o klucz tajny klienta, aby uniknąć przechowywania go w aplikacji rozproszonej na urządzeniach.

Fragment poniżej z: https://dev.fitbit.com/docs/oauth2/

Przepływ Przyznanie kodu autoryzacji jest zalecany dla aplikacji, które mają usługę sieci Web. Ten przepływ wymaga komunikacji między serwerami przy użyciu klucza tajnego klienta aplikacji.

Uwaga: nigdy nie umieszczaj klucza tajnego klienta w kodzie rozproszonym, takim jak aplikacje pobrane za pośrednictwem sklepu z aplikacjami lub JavaScript po stronie klienta.

Aplikacje, które nie mają usługi sieci Web, powinny używać przepływu niejawnego przyznania.

Wniosek

Ostateczna decyzja powinna uwzględniać pożądane wrażenia użytkownika, ale także apetyt na ryzyko po przeprowadzeniu właściwej oceny ryzyka dla wybranych podejść i lepszym zrozumieniu konsekwencji.

Świetna lektura jest tutaj https://auth0.com/blog/oauth-2-best-practices-for-native-apps/

Inny to https://www.oauth.com/oauth2-servers/oauth-native-apps/, który stwierdza

Bieżąca najlepsza praktyka branżowa polega na korzystaniu z przepływu autoryzacji z pominięciem klucza tajnego klienta oraz przy użyciu zewnętrznego agenta użytkownika do ukończenia przepływu. Zewnętrzny klient użytkownika jest zwykle natywną przeglądarką urządzenia (z domeną zabezpieczeń oddzielną od aplikacji natywnej), dzięki czemu aplikacja nie może uzyskać dostępu do magazynu plików cookie ani sprawdzać lub modyfikować zawartości strony w przeglądarce.

Uwzględnienie PKCE

Powinieneś również wziąć pod uwagę PKCE, które jest opisane tutaj https://www.oauth.com/oauth2-servers/pkce/

W szczególności, jeśli wdrażasz również serwer autoryzacji, https://www.oauth.com/oauth2-servers/oauth-native-apps/checklist-server-support-native-apps/ stwierdza, że ​​należy

  • Zezwalaj klientom na rejestrowanie niestandardowych schematów adresów URL dla ich przekierowań.
  • Obsługa adresów URL przekierowań pętli zwrotnej IP z dowolnymi numerami portów w celu obsługi aplikacji komputerowych.
  • Nie zakładaj, że aplikacje natywne mogą zachować tajemnicę. Wymagaj od wszystkich aplikacji, aby deklarowały, czy są publiczne, czy poufne, i wysyłaj klucze klienta tylko do poufnych aplikacji.
  • Obsługuj rozszerzenie PKCE i wymagaj, aby używali go klienci publiczni.
  • Spróbuj wykryć, kiedy interfejs autoryzacji jest osadzony w widoku sieci Web aplikacji natywnej, zamiast uruchamiać go w przeglądarce systemowej, i odrzuć te żądania.

Uwzględnienie widoków internetowych

Istnieje wiele przykładów korzystania z widoków internetowych, np. Wbudowanego klienta użytkownika, ale należy unikać tego podejścia (zwłaszcza gdy aplikacja nie jest własna), aw niektórych przypadkach może spowodować zakaz używania interfejsu API jako fragmentu poniżej stąd demonstruje

Każda próba osadzenia strony uwierzytelniającej OAuth 2.0 spowoduje zablokowanie aplikacji w Fitbit API.

Ze względów bezpieczeństwa strona autoryzacji OAuth 2.0 musi być prezentowana w dedykowanym widoku przeglądarki. Użytkownicy Fitbit mogą potwierdzić, że uwierzytelniają się na prawdziwej stronie Fitbit.com tylko wtedy, gdy posiadają narzędzia dostarczone przez przeglądarkę, takie jak pasek adresu URL i informacje o certyfikacie Transport Layer Security (TLS).

W przypadku aplikacji natywnych oznacza to, że strona autoryzacji musi otwierać się w domyślnej przeglądarce. Aplikacje natywne mogą używać niestandardowych schematów adresów URL jako identyfikatorów URI przekierowania w celu przekierowania użytkownika z powrotem z przeglądarki do aplikacji żądającej pozwolenia.

Aplikacje dla systemu iOS mogą używać klasy SFSafariViewController zamiast przełączać się na Safari. Używanie klasy WKWebView lub UIWebView jest zabronione.

Aplikacje na Androida mogą używać niestandardowych kart Chrome zamiast przełączać się na domyślną przeglądarkę. Korzystanie z WebView jest zabronione.

W celu dalszego wyjaśnienia, oto cytat z tej sekcji z poprzedniego projektu odnośnika do najlepszych praktyk podanego powyżej

Osadzone klienty użytkownika, powszechnie implementowane z widokami internetowymi, są alternatywną metodą autoryzacji aplikacji natywnych. Z definicji są one jednak niebezpieczne dla osób trzecich. Obejmują one logowanie użytkownika przy użyciu pełnych danych logowania, tylko po to, aby obniżyć ich zakres do mniej wydajnych poświadczeń OAuth.

Nawet gdy są używane przez zaufane aplikacje własne, wbudowane programy klienckie naruszają zasadę najniższych przywilejów, uzyskując silniejsze dane uwierzytelniające niż potrzebują, potencjalnie zwiększając powierzchnię ataku.

W typowych implementacjach wbudowanych agentów użytkownika, opartych na widoku sieci Web, aplikacja hosta może: rejestrować każde naciśnięcie klawisza wprowadzone w formularzu w celu przechwycenia nazw użytkowników i haseł; automatyczne przesyłanie formularzy i pomijanie zgody użytkownika; kopiować sesyjne pliki cookie i używać ich do wykonywania uwierzytelnionych działań jako użytkownik.

Zachęcanie użytkowników do wprowadzania poświadczeń we wbudowanym widoku internetowym bez zwykłego paska adresu i innych funkcji tożsamości, które mają przeglądarki, uniemożliwia użytkownikowi sprawdzenie, czy logują się do legalnej witryny, a nawet gdy są, szkoli ich że można wprowadzić poświadczenia bez uprzedniej weryfikacji witryny.

Oprócz obaw związanych z bezpieczeństwem, widoki internetowe nie dzielą stanu uwierzytelnienia z innymi aplikacjami lub przeglądarką systemową, co wymaga od użytkownika logowania się w przypadku każdego żądania autoryzacji i prowadzi do złego doświadczenia użytkownika.

W związku z powyższym NIE ZALECA SIĘ korzystania z wbudowanych klientów użytkownika, z wyjątkiem sytuacji, gdy zaufana własna aplikacja działa jako zewnętrzny agent użytkownika dla innych aplikacji lub zapewnia jednokrotne logowanie do wielu aplikacji własnych.

Serwery autoryzacji POWINNY rozważyć podjęcie kroków mających na celu wykrycie i zablokowanie logowania za pośrednictwem wbudowanych agentów użytkownika, które nie są ich własnymi, jeśli to możliwe.

Poruszono również kilka interesujących kwestii: /security/179756/why-are-developers-using-embedded-user-agents-for-3rd-party-auth-what-are-the- za

Matt C
źródło
3
20 kwietnia 2017 Google wyłącza obsługę wyświetleń w sieci Web Developers.googleblog.com/2016/08/…
Matt C
Do Twojej wiadomości dokument odwołuje się na początku tej odpowiedzi, jeśli nie jest już szkicem
Kostiantyn
Dzięki @KostiantynSokolinskyi, zredagowano odpowiednio z linkiem do rfc, który nie jest już wersją roboczą
Matt C
@MattC Jaki jest najlepszy sposób na wdrożenie rejestracji nowego użytkownika? Czy powinniśmy to zrobić w aplikacji czy na IDP? Czy można automatycznie zalogować się do rejestru użytkownika? stackoverflow.com/questions/60187173/…
Yashvit
Przepraszam, jestem zdezorientowany niektórymi szczegółami ... Czy mógłbyś rzucić okiem? Dzięki! link ---> stackoverflow.com/q/61313694/4619958
ch271828n
25

Niestety nie wydaje mi się, aby istniała jasna odpowiedź na to pytanie. Oto jednak opcje, które zidentyfikowałem:

  • Jeśli możesz poprosić użytkownika o jego / jej poświadczenia, użyj poświadczeń hasła właściciela zasobu . Jednak może to nie być możliwe z pewnych powodów, a mianowicie

    • Zasady dotyczące użyteczności lub bezpieczeństwa zabraniają wprowadzania hasła bezpośrednio w aplikacji
    • Proces uwierzytelniania jest delegowany na zewnętrznego dostawcę tożsamości i musi być wykonywany za pośrednictwem przepływu opartego na przekierowaniach HTTP (np. OpenID, SAMLP lub WS-Federation)
  • Jeśli wymagane jest użycie przepływu opartego na przeglądarce, użyj przepływu kodu autoryzacji . Tutaj definicja redirect_urijest dużym wyzwaniem, dla którego istnieją następujące opcje:

    • Użyj techniki opisanej na https://developers.google.com/accounts/docs/OAuth2InstalledApp , gdzie specjalny redirect_uri(np. urn:ietf:wg:oauth:2.0:oob) Sygnalizuje punktowi końcowemu autoryzacji, aby wyświetlał kod autoryzacji zamiast przekierowywania z powrotem do aplikacji klienckiej. Użytkownik może ręcznie skopiować ten kod lub aplikacja może spróbować uzyskać go z tytułu dokumentu HTML.
    • Skorzystaj z localhostserwera przy urządzeniu (zarządzanie portem może nie być łatwe).
    • Użyj niestandardowego schematu URI (np. myapp://...), Który po wyłuskowaniu wywołuje zarejestrowaną „procedurę obsługi” (szczegóły zależą od platformy mobilnej).
    • Jeśli to możliwe, użyj specjalnego „widoku internetowego”, takiego jak WebAuthenticationBroker w systemie Windows 8, aby kontrolować i uzyskiwać dostęp do odpowiedzi przekierowania HTTP.

Mam nadzieję że to pomoże

Pedro

Pedro Felix
źródło
Dzięki Pedro za wkład !. Tak, wygląda na to, że przepływ kodu autoryzacji z niestandardowym schematem URI lub widok sieciowy wydaje się tutaj najlepszą opcją.
Pablo Cibraro
1
Wszystko zależy od tego, czy chcesz, aby klient wpisał hasło w widoku sieci Web, czy w aplikacji klienckiej. Jeśli to możliwe, wolałbym aplikację kliencką - wtedy natychmiast zamień sekret na token dostępu / odświeżania.
najmniejprivilege
Dzięki Dominick !. Mój klient używa ADFS do uwierzytelniania użytkowników, więc chce wprowadzić poświadczenia na stronie logowania. Widok sieciowy będzie działał dla nich
Pablo Cibraro
5
Jestem ciekawy, dlaczego poleciłbyś „przepływ kodu autoryzacyjnego”? Czy nie potrzebowałbyś client_secret i client_id do wymiany kodu na access_token? Pomyślałem, że „niejawny” przepływ został zaprojektowany dla tych scenariuszy, ponieważ nie wymaga przechowywania sekretów w urządzeniu.
Eugenio Pace
1
niejawne nie obsługuje tokenów odświeżania OOB. W scenariuszu Pablo - zdecydowanie poleciłbym przepływ RO. Wygląda na to, że firma wdrożyła aplikacje na tym samym zapleczu firmy.
najmniejprivilege
9

TL; DR: Przyznanie kodu autoryzacji z PKCE

1. Niejawny typ przyznania

Niejawny typ grantu jest dość popularny w aplikacjach mobilnych. Ale to nie miało być używane w ten sposób. Wokół przekierowania istnieją obawy dotyczące bezpieczeństwa. Justin Richer stwierdza :

Problem pojawia się, gdy zdasz sobie sprawę, że w przeciwieństwie do adresu URL zdalnego serwera, nie ma niezawodnego sposobu na zapewnienie, że powiązanie między danym identyfikatorem URI przekierowania a określoną aplikacją mobilną jest honorowane. Każda aplikacja na urządzeniu może próbować wstawić się do procesu przekierowania i spowodować, że będzie obsługiwać identyfikator URI przekierowania. I zgadnij co: jeśli użyłeś niejawnego przepływu w swojej natywnej aplikacji, po prostu przekazałeś atakującemu swój token dostępu. Od tego momentu nie ma możliwości odzyskania danych - mają token i mogą go używać.

A wraz z tym, że nie pozwala odświeżyć tokena dostępu, lepiej tego unikaj.

2. Typ nadania kodu autoryzacji

Przyznanie kodu autoryzacji wymaga klucza tajnego klienta. Nie należy jednak przechowywać poufnych informacji w kodzie źródłowym aplikacji mobilnej. Ludzie mogą je wyodrębnić. Aby nie ujawniać tajemnicy klienta, musisz uruchomić serwer jako pośrednik, jak pisze Facebook :

Zalecamy używanie tokenów dostępu do aplikacji wyłącznie bezpośrednio z serwerów aplikacji w celu zapewnienia najwyższego poziomu bezpieczeństwa. W przypadku aplikacji natywnych sugerujemy, aby aplikacja komunikowała się z Twoim własnym serwerem, a serwer wysyła następnie żądania API do Facebooka przy użyciu tokenu dostępu do aplikacji.

Nie jest to idealne rozwiązanie, ale jest nowy, lepszy sposób wykonywania OAuth na urządzeniach mobilnych: Proof Key for Code Exchange

3. Typ nadania kodu autoryzacji z PKCE (klucz potwierdzający wymianę kodu)

Z ograniczeń stworzono nową technikę, która umożliwia korzystanie z kodu autoryzacyjnego bez klucza klienta. Możesz przeczytać pełny dokument RFC 7636 lub to krótkie wprowadzenie .

PKCE (RFC 7636) to technika zabezpieczania klientów publicznych, którzy nie używają tajemnicy klienta.

Jest używany głównie przez aplikacje natywne i mobilne, ale można ją również zastosować do dowolnego klienta publicznego. Wymaga dodatkowej obsługi przez serwer autoryzacyjny, więc jest obsługiwana tylko przez niektórych dostawców.

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

Johannes Filter
źródło
-3

Korzystanie z widoku internetowego w aplikacji mobilnej powinno być niedrogim sposobem implementacji protokołu OAuth2.0 na platformie Android.

Jeśli chodzi o pole redirect_uri, myślę, że http://localhostjest to dobry wybór i nie musisz portować serwera HTTP wewnątrz swojej aplikacji, ponieważ możesz przesłonić implementację onPageStartedfunkcji w WebViewClientklasie i zatrzymać ładowanie strony internetowej od http://localhostmomentu sprawdzenia urlparametru.

public void onPageStarted(final WebView webView, final String url,
        final Bitmap favicon) {}
Zefir
źródło
3
Najlepsze praktyki dotyczące aplikacji natywnych korzystających z OAuth2: tools.ietf.org/html/draft-wdenniss-oauth-native-apps
Matt C
1
Jak powiedział Matt C. powyżej. Widoki internetowe to zły pomysł dla aplikacji mobilnych - są niezabezpieczone, pozwalają aplikacji uzyskać dostęp do poświadczeń (więc nie są bezpieczniejsze niż RO) i nie pozwalają użytkownikom na weryfikację domeny i certyfikatów TLS. Użyj typu przyznania kodu uwierzytelniającego z niestandardową obsługą URI i upewnij się, że używasz kodu dowodowego dla wymiany kluczy (PKCE), aby uniemożliwić złośliwym aplikacjom w telefonie przechwytywanie kodu uwierzytelniającego i uzyskiwanie dostępu do interfejsu API.
ChrisC
2
Zaktualizowana wersja dokumentu zawierającego najlepsze praktyki dotyczące protokołu OAuth 2.0 dla aplikacji natywnych jest dostępna pod adresem tools.ietf.org/html/draft-ietf-oauth-native-apps
Jeff Olson
-4

Najłatwiejszym sposobem uwierzytelniania i najłatwiejszym do zaimplementowania jest umieszczenie widoku internetowego w aplikacji. Przetwarzaj odpowiedzi otrzymane przez przeglądarkę internetową z punktu uwierzytelniania i wykryj błąd (anulowanie użytkownika) lub zatwierdzenie (i wyodrębnij token z parametrów zapytania adresu URL). Myślę, że możesz to zrobić na wszystkich platformach. Z powodzeniem wykonałem tę pracę dla następujących aplikacji: iOS, Android, Mac, Windows Store 8.1, Windows Phone 8.1. Zrobiłem to dla następujących usług: dropbox, dysk Google, onedrive, box, basecamp. W przypadku platform innych niż Windows korzystałem z platformy Xamarin, która rzekomo nie ujawnia wszystkich interfejsów API specyficznych dla platformy, ale ujawniła wystarczająco dużo, aby było to możliwe. Jest to więc całkiem przystępne rozwiązanie, nawet z perspektywy wielu platform.

Radu Simionescu
źródło
Zapewniając wygodę użytkowania, będziemy świadkami odejścia branży od tego podejścia. Ponieważ widoki internetowe stwarzają możliwość złamania haseł, kiedy jestem proszony o podanie poświadczeń przez wbudowanego klienta użytkownika, odinstalowałbym aplikację. Niektóre interfejsy API zakazują teraz nawet takich integracji, jak ta dev.fitbit.com/docs/oauth2
Matt C
Najlepsze praktyki dotyczące aplikacji natywnych korzystających z OAuth2: tools.ietf.org/html/draft-wdenniss-oauth-native-apps
Matt C
Nie rozumiem, jak usługa z włączoną obsługą OAuth mogłaby zakazać tego podejścia. Jest niewykrywalny i bezpieczny ... Niektóre usługi z włączoną obsługą OAuth udostępniają klientów specyficznych dla platformy w celu ułatwienia uwierzytelniania, a tacy klienci faktycznie robią to, co tutaj opisałem (wyświetlają osadzony widok sieciowy i śledzą zmiany adresu URL). Najlepsza praktyka, którą podałeś, zaleca to samo: użyj przeglądarki systemowej lub wbudowanego widoku internetowego. Jaki argument atakujesz w mojej odpowiedzi? to jest niejasne.
Radu Simionescu
Żaden atak nie zamierzał, tylko podkreślenie problemu. Link mówi, że istnieją 2 podejścia, o których wspomniałeś, ale tylko zewnętrzny klient użytkownika może być uważany za bezpieczny, a konkretnie mówi, że opcje dla aplikacji natywnych są „za pośrednictwem wbudowanego klienta użytkownika lub zewnętrznego klienta użytkownika. klienty użytkownika, takie jak karty przeglądarki w aplikacji, jako jedyna bezpieczna i użyteczna opcja dla protokołu OAuth ”.
Matt C
Dalszy cytat „W typowych implementacjach wbudowanych agentów użytkownika opartych na przeglądarce internetowej aplikacja hosta może: rejestrować każde naciśnięcie klawisza wprowadzonego w formularzu w celu przechwycenia nazw użytkowników i haseł; automatycznie przesyłać formularze i omijać zgodę użytkownika” ....... „Korzystanie z wbudowanych klientów użytkownika NIE JEST ZALECANE, z wyjątkiem sytuacji, gdy zaufana własna aplikacja działa jako zewnętrzny agent użytkownika dla innych aplikacji lub zapewnia jednokrotne logowanie do wielu własnych aplikacji. Serwery autoryzacji POWINNY rozważyć podjęcie kroków w celu tam, gdzie to możliwe, wykrywa i blokuje logowanie za pośrednictwem wbudowanych agentów użytkownika, które nie są ich własnymi ”.
Matt C