Jaka jest różnica między kodem autoryzacji OAuth a niejawnymi przepływami pracy? Kiedy używać każdego z nich?

165

OAuth 2.0 ma wiele przepływów pracy. Mam kilka pytań dotyczących tych dwóch.

  1. Przepływ kodu autoryzacji - użytkownik loguje się z aplikacji klienckiej, serwer autoryzacji zwraca kod autoryzacji do aplikacji. Następnie aplikacja wymienia kod autoryzacyjny na token dostępu.
  2. Niejawny przepływ przyznania - użytkownik loguje się z aplikacji klienckiej, serwer autoryzacji wystawia token dostępu bezpośrednio do aplikacji klienckiej.

Jaka jest różnica między tymi dwoma podejściami w zakresie bezpieczeństwa? Który z nich jest bezpieczniejszy i dlaczego?

Nie widzę powodu, dla którego dodatkowy krok (wymiana kodu autoryzacji na token) jest dodawany w jednym przepływie pracy, gdy serwer może bezpośrednio wystawić token Access.

Różne witryny internetowe podają, że przepływ kodu autoryzacji jest używany, gdy aplikacja kliencka może zapewnić bezpieczeństwo poświadczeń. Czemu?

divyanshm
źródło
Przewodnik po
dotacjach

Odpowiedzi:

204

To access_tokenjest to, czego potrzebujesz, aby wywołać chroniony zasób (interfejs API). W przepływie kodu autoryzacyjnego są 2 kroki, aby go uzyskać:

  1. Użytkownik musi uwierzytelnić się i codezwrócić konsumentowi interfejsu API (nazywanego „Klientem”).
  2. „Klient” interfejsu API (zwykle serwer WWW) wymienia codeotrzymane w # 1 na access_token, uwierzytelniając się za pomocą client_idiclient_secret
  3. Następnie może wywołać interfejs API z rozszerzeniem access_token.

Tak więc istnieje podwójna kontrola: użytkownik, który jest właścicielem zasobów udostępnionych przez API i klient korzystający z API (np. Aplikacja internetowa). Oba są sprawdzane pod kątem przyznania dostępu. Zwróć uwagę na „autoryzacyjny” charakter protokołu OAuth: użytkownik udziela dostępu do swojego zasobu (poprzez codezwracany po uwierzytelnieniu) aplikacji, aplikacja pobiera an access_tokeni wywołuje w imieniu użytkownika.

W niejawnym przepływie krok 2 jest pomijany. Dlatego po uwierzytelnieniu użytkownika access_tokenzwracany jest bezpośrednio znak, którego można użyć w celu uzyskania dostępu do zasobu. API nie wie, kto wywołuje ten interfejs API. Każdy, kto ma taką access_tokenmożliwość, podczas gdy w poprzednim przykładzie tylko aplikacja internetowa (jej elementy wewnętrzne zwykle nie są dostępne dla nikogo).

Niejawny przepływ jest zwykle używany w scenariuszach, w których przechowywanie client idi client secretnie jest zalecane (na przykład urządzenie, chociaż wiele z nich i tak to robi). To właśnie oznacza wyłączenie odpowiedzialności. Ludzie mają dostęp do kodu klienta i dlatego mogą uzyskać poświadczenia i udawać, że są klientami zasobów. W niejawnym przepływie wszystkie dane są ulotne i nic nie jest przechowywane w aplikacji.

Eugenio Pace
źródło
Dziękujemy za wyjaśnienie, ale nie rozumiem, dlaczego potrzebujemy kolejnego przepływu kodu autoryzacyjnego. Możemy osiągnąć ten sam wynik na serwerze przez niejawny przepływ (access_token) i odświeżanie tokena. Wygląda na to, że jedynym aspektem bezpieczeństwa niejawnego przepływu jest to, że kod_dostępu powinien mieć krótką żywotność, więc nie można go używać na serwerze z serwerem. OK, ale token odświeżania rozwiązuje ten problem. Dlaczego powinniśmy używać przepływu auth_code i żądać access_token na serwerze, aby uzyskać access_code?
Mohammad Nikravan,
Cóż ... tak działa protokół. Możesz przeczytać specyfikację analizy zagrożeń, aby uzyskać bardziej szczegółowe informacje na temat zalet bezpieczeństwa jednego i drugiego.
Eugenio Pace
Wiem, że oryginalna odpowiedź ma ponad 5 lat, ale jest to najprostsze i najczystsze wyjaśnienie, jakie kiedykolwiek czytałem. Dziękuję @EugenioPace
Taha Ahmad
1
@ Madnik7G Powód jest prostopadły do ​​tego, co wyjaśnia ta odpowiedź (pięknie): może być zaangażowana strona trzecia. Cały przepływ jest zarządzany przez klienta użytkownika (np. Przeglądarkę), ale na końcu serwer autoryzacji (np. „Zaloguj się przez Facebooka”) będzie rozmawiał bezpośrednio z klientem (powiedzmy, BFF po stronie serwera), który ostatecznie uzyskaj dostęp do zasobu, tak aby agent użytkownika nigdy nie miał bezpośredniego dostępu.
Daniel Langdon,
Dzięki! Tak, odbywają się 3 komunikaty: przeglądarka i AS 9 np. Facebook). Taka jest /authorizeprośba. Przeglądarka i witryna internetowa próbująca wywołać interfejs API (nazywana też klientem). To jest redirect_uri+ codezwracany przez AS po pomyślnym uwierzytelnieniu. Na koniec klient dzwoni do AS za kulisami, zamieniając codeplik access_token. To jest token endpointw literaturze. Generalnie AS nigdy do nikogo nie dzwoni. Zawsze odpowiada.
Eugenio Pace
52

Dodam tutaj coś, co nie wydaje mi się jasne w powyższych odpowiedziach:

  • Przepływ kodu autoryzacji pozwala, aby końcowy token dostępu nigdy nie dotarł i nigdy nie był przechowywany na komputerze z przeglądarką / aplikacją . Tymczasowy kod autoryzacyjny jest przekazywany maszynie z przeglądarką / aplikacją, która jest następnie wysyłana na serwer. Serwer może wówczas zamienić go na token pełnego dostępu i mieć dostęp do API itp. Użytkownik posiadający przeglądarkę uzyskuje dostęp do API tylko przez serwer z tokenem.
  • Niejawny przepływ może obejmować tylko dwie strony, a ostateczny token dostępu jest przechowywany na kliencie z przeglądarką / aplikacją. Jeśli przejęto tę przeglądarkę / aplikację, ich token uwierzytelnienia może być niebezpieczny.

tl; dr nie używają przepływu niejawny jeśli nie ufasz maszynę użytkowników do tokenów ładowni ale zrobić zaufać własnych serwerów.

George Powell
źródło
12
re: Użytkownik z przeglądarką uzyskuje dostęp do API tylko przez serwer z tokenem. Ale serwer musi wysłać coś do przeglądarki, aby żądania przychodzące mogły być powiązane z tokenem przechowywanym po stronie serwera. Ciasteczko, jeśli chcesz. Jeśli serwer nie przesyła tokena do JS działającego w przeglądarce, musi przesłać coś innego, co klient (przeglądarki) musi przekazać na serwer, aby umożliwić serwerowi działanie w imieniu konkretnego klienta.
Cheeso
Tak, ciastko. Dlatego należy tak skonfigurować serwer i klienta przeglądarki, aby były chronione przed fałszowaniem żądań między lokacjami.
Marcel
@Marcel Chciałbym wiedzieć, że jak już dostaniemy kod, jak i gdzie zdarzy się, że wymiana uzyska faktyczną access_tokenza pomocą authorization code.
chirag soni
14

Różnica między nimi polega na tym, że:

  1. W przepływie niejawnym token jest zwracany bezpośrednio przez adres URL przekierowania ze znakiem „#” i jest to używane głównie w klientach javascript lub aplikacjach mobilnych, które nie mają własnej strony serwera, a klient nie musi podawać swojego sekretu w niektórych implementacjach .

  2. W przepływie kodu autoryzacji kod jest zwracany z „?” aby był możliwy do odczytania przez serwer, strona serwera musi tym razem podać klucz klienta do url tokenu, aby uzyskać token jako obiekt json z serwera autoryzacji. Jest używany w przypadku, gdy masz serwer aplikacji, który może to obsłużyć i przechowywać token użytkownika ze swoim profilem we własnym systemie i jest używany głównie do popularnych aplikacji mobilnych.

więc zależy to od rodzaju aplikacji klienckiej, który z nich jest bardziej bezpieczny, ponieważ żąda tajnego klucza na kliencie, a token może być przesyłany między serwerem autoryzacyjnym a aplikacją kliencką na bardzo zabezpieczonym połączeniu, a dostawca autoryzacji może ogranicz niektórym klientom używanie tylko „kodu autoryzacji” i nie zezwalaj na niejawne

Bassem Reda Zohdy
źródło
Kod autoryzacyjny jest przechowywany po stronie serwera przez 10 minut na Facebooku. Zostało to wydane w ich zmianie z 5 grudnia 2012 roku. Moje pytanie dotyczy głównie tego, jaka jest różnica między 2 pod względem bezpieczeństwa / wydajności. Wiem, co robią oba przepływy - ale jakie są zalety używania kodu autoryzacyjnego - dodając jeszcze jeden krok do przepływu pracy.
divyanshm
nie wysyła tokena do aplikacji użytkownika, bezpośrednie połączenie między aplikacją kliencką a serwerem autoryzacji jest ukryte przed użytkownikiem, a jak wspomniałem, może to być bardzo zabezpieczony kanał, inny niż ten od użytkownika do aplikacji klienckiej.
Bassem Reda Zohdy
wydajność w kodzie autoryzacji, trafiasz dwukrotnie na serwer autoryzacji, więc zajmuje to więcej czasu, również serwer klienta będzie przechowywać token użytkownika, a to również wydłuży czas.
Bassem Reda Zohdy
2
Och w porządku! Mogłem to przeoczyć. Zasadniczo przepływ kodu autoryzacyjnego ma być używany przez systemy, w których klientem jest cały serwer - przeglądarka wysyła żądanie i pobiera kod. kod jest wysyłany do serwera klienta, który bezpiecznie łączy się z serwerem zasobów. Czy dobrze to rozumiem? Token dostępu nigdy nie dociera do komputera użytkownika końcowego?
divyanshm
1
Token dostępu nigdy nie dociera do komputera użytkownika końcowego? tak, jest powiązany z Twoim profilem z serwerem aplikacji klienta.
Bassem Reda Zohdy
4

Niejawne przyznanie jest podobne do nadania kodu autoryzacji z dwiema odrębnymi różnicami.

Jest przeznaczony do użytku dla klientów opartych na agentach użytkownika (np. Jednostronicowych aplikacji internetowych), które nie mogą utrzymywać klienta w tajemnicy, ponieważ cały kod aplikacji i pamięć masowa są łatwo dostępne.

Po drugie, zamiast zwracania przez serwer autoryzacji kodu autoryzacji, który jest wymieniany na token dostępu, serwer autoryzacyjny zwraca token dostępu.

Szczegóły znajdziesz tutaj http://oauth2.thephpleague.com/authorization-server/which-grant/

Lutfor
źródło
1
Dzięki za ten link, pomogło mi zrozumieć różnicę między każdym typem grantu i kiedy wybrać każdy z nich.
François POYER
3

Niejawny przepływ

Zalety

  • Najprostszy do wdrożenia

Niedogodności

  • Dostęp do tokenów widocznych dla przeglądarki
  • Nie można określić pochodzenia tokenów dostępu
  • Tokeny dostępu nie mogą wygasać (zgodnie z zasadami Google)

Przepływ kodu autoryzacji

Zalety

  • Najbezpieczniejszy
  • Tokeny dostępu i tokeny odświeżania można tworzyć tylko wtedy, gdy znany jest wspólny sekret
  • Można rozszerzyć o nowe funkcje bezpieczeństwa i UX, gdy staną się dostępne

Niedogodności

  • Musi zaimplementować wiele punktów końcowych uwierzytelniania

Cytowanie: https://developers.google.com/actions/develop/identity/oauth2-overview#supported_oauth_20_flows

vlazzle
źródło
2

Pozwólcie, że podsumuję punkty, których nauczyłem się z powyższych odpowiedzi i dodam kilka własnych wniosków.

Przepływ kodu autoryzacji !!!

  • Jeśli masz serwer aplikacji sieci Web, który działa jako klient OAuth
  • Jeśli chcesz mieć długotrwały dostęp
  • Jeśli chcesz mieć dostęp do danych w trybie offline
  • gdy odpowiadasz za wywołania API, które wykonuje Twoja aplikacja
  • Jeśli nie chcesz ujawniać swojego tokena OAuth
  • Jeśli nie chcesz, aby Twoja aplikacja przechodziła przez proces autoryzacji za każdym razem, gdy potrzebuje dostępu do danych. UWAGA: Przepływ Implicit Grant nie obsługuje tokenu odświeżania, więc jeśli serwer autoryzacji regularnie wygaśnie tokeny dostępu, aplikacja będzie musiała przejść przez przepływ autoryzacji za każdym razem, gdy będzie potrzebować dostępu.

Niejawny przepływ dotacji !!!

  • Gdy nie masz serwera aplikacji sieci Web działającego jako klient OAuth
  • Jeśli nie potrzebujesz długoterminowego dostępu, tj. Wymagany jest tylko tymczasowy dostęp do danych.
  • Jeśli ufasz przeglądarce, w której działa Twoja aplikacja, i istnieją ograniczone obawy, że token dostępu wycieknie do niezaufanych użytkowników.
Aman Tuladhar
źródło
2

Który z nich jest bezpieczniejszy i dlaczego?

Oba są bezpieczne, zależy to od środowiska, w którym go używasz.

Nie widzę powodu, dla którego dodatkowy krok (wymiana kodu autoryzacji na token) jest dodawany w jednym przepływie pracy, gdy serwer może bezpośrednio wystawić token Access.

To jest proste. Twój klient nie jest bezpieczny. Zobaczmy to szczegółowo.

Weź pod uwagę, że tworzysz aplikację przeciwko Instagram API, więc rejestrujesz swoją aplikację Instagrami określasz, której API'spotrzebujesz. Instagramzapewni Ci client_idiclient_secrect

Na swojej stronie internetowej ustawiasz link, który mówi. „Przyjdź i użyj mojej aplikacji”. Kliknięcie tej aplikacji internetowej powinno wywołać dwa wywołania Instagram API.

Firstwyślij zapytanie do Instagram Authentication Serverz poniższymi parametrami.

1. `response_type` with the value `code`
2. `client_id` you have get from `Instagram`
3. `redirect_uri` this is a url on your server which do the second call
4. `scope` a space delimited list of scopes
5. `state` with a CSRF token. 

Nie wysyłaszclient_secret , nie możesz zaufać klientowi (Użytkownikowi i / lub jego przeglądarce, która próbuje użyć Twojej aplikacji). Klient może zobaczyć adres URL lub skrypt java i client_secrectłatwo znaleźć plik. Dlatego potrzebujesz kolejnego kroku.

Otrzymujesz codei state. codeTu jest temporaryi nie jest zapisany w każdym miejscu.

Następnie seconddzwonisz do Instagram API(ze swojego serwera)

 1. `grant_type` with the value of `authorization_code`
 2. `client_id` with the client identifier
 3. `client_secret` with the client secret
 4. `redirect_uri` with the same redirect URI the user was redirect back to
 5. `code` which we have already received.

Ponieważ połączenie jest wykonywane z naszego serwera, możemy bezpiecznie użyć client_secret(co pokazuje, jak jesteśmy), z codektórego pokazuje, że użytkownik zezwolił client_idna korzystanie z zasobu.

W odpowiedzi będziemy mieć access_token

Alireza Fattahi
źródło
1

Z praktycznego punktu widzenia (co zrozumiałem), głównym powodem posiadania przepływu kodu Authz jest:

  1. Obsługa tokenów odświeżania (długoterminowy dostęp przez aplikacje w imieniu użytkownika), nieobsługiwana w sposób niejawny: patrz: https://tools.ietf.org/html/rfc6749#section-4.2
  2. Obsługa strony zgody, która jest miejscem, w którym właściciel zasobu może kontrolować, jaki dostęp ma zapewnić (rodzaj strony uprawnień / autoryzacji, którą widzisz w google). Tego samego nie ma w domyśle. Zobacz sekcję: https://tools.ietf.org/html/rfc6749#section-4.1 , punkt (B)

„Serwer autoryzacji uwierzytelnia właściciela zasobu (za pośrednictwem agenta użytkownika) i ustala, czy właściciel zasobu przyznaje, czy odrzuca żądanie dostępu klienta”

Poza tym, korzystając z tokenów odświeżania, aplikacje mogą uzyskać długoterminowy dostęp do danych użytkownika.

dvsakgec
źródło
0

Wydaje się, że istnieją dwa kluczowe punkty, dotychczas nie omówione, które wyjaśniają, dlaczego objazd w ramach typu przyznania kodu autoryzacji zwiększa bezpieczeństwo.

Krótka historia : Przyznanie kodu autoryzacji przechowuje poufne informacje z historii przeglądarki, a transmisja tokena zależy tylko od ochrony serwera autoryzacyjnego HTTPS.

Dłuższa wersja:

W dalszej części będę trzymał się terminologii OAuth 2 zdefiniowanej w RFC (to szybki odczyt): serwer zasobów , klient , serwer autoryzacji , właściciel zasobów .

Wyobraź sobie, że chcesz, aby aplikacja innej firmy (= klient) miała dostęp do określonych danych Twojego konta Google (= serwer zasobów). Załóżmy po prostu, że Google używa OAuth 2. Jesteś właścicielem zasobów konta Google, ale w tej chwili obsługujesz aplikację innej firmy.

Najpierw klient otwiera przeglądarkę, aby wysłać Cię pod bezpieczny adres URL serwera autoryzacji Google. Następnie zatwierdzasz żądanie dostępu, a serwer autoryzacji odsyła Cię z powrotem do adresu URL przekierowania podanego wcześniej przez klienta, z kodem autoryzacji w ciągu zapytania. A teraz dwie kluczowe kwestie:

  1. Adres URL tego przekierowania trafia do historii przeglądarki . Dlatego nie chcemy tutaj długowiecznego, bezpośrednio używalnego tokenu dostępu. Krótkotrwały kod autoryzacji jest mniej niebezpieczny w historii. Należy zauważyć, że typ Niejawnego Grantu powoduje umieszczenie tokenu w historii.
  2. Bezpieczeństwo tego przekierowania zależy od certyfikatu HTTPS klienta , a nie od certyfikatu Google. Otrzymujemy więc bezpieczeństwo transmisji klienta jako dodatkowy wektor ataku (aby było to nieuniknione, klient musi być bez JavaScript. W przeciwnym razie moglibyśmy przesłać kod autoryzacji przez fragment URL, gdzie kod nie przeszedłby przez sieć. może to być powodem niejawny Grant Typ, który robi użyć adresu URL fragment kiedyś zalecane dla klientów JavaScript, mimo że nie jest już tak).

W przypadku Authorization Code Grant Type token jest ostatecznie uzyskiwany poprzez wywołanie od klienta serwera autoryzacyjnego, gdzie bezpieczeństwo transmisji zależy tylko od serwera autoryzacyjnego , a nie od klienta.

Carsten Führmann
źródło