Opis niejawnego przepływu udzielania OAuth2 w usłudze Azure Active Directory (AD)

Ostrzeżenie

Ta zawartość jest przeznaczona dla starszego punktu końcowego Azure AD w wersji 1.0. Użyj Platforma tożsamości Microsoft dla nowych projektów.

Niejawne udzielanie OAuth2 jest notorycznie przyznawanie z najdłuższą listą problemów z zabezpieczeniami w specyfikacji OAuth2. A jednak jest to podejście zaimplementowane przez bibliotekę ADAL JS i to, które zalecamy podczas pisania aplikacji SPA. Co daje? To wszystko jest kwestia kompromisów: i jak się okazuje, niejawne przyznanie jest najlepszym podejściem, które można realizować w przypadku aplikacji korzystających z internetowego interfejsu API za pośrednictwem języka JavaScript w przeglądarce.

Co to jest niejawne udzielanie OAuth2?

Kwintesencja przyznawania kodu autoryzacji OAuth2 to udzielenie autoryzacji , które używa dwóch oddzielnych punktów końcowych. Punkt końcowy autoryzacji jest używany do fazy interakcji użytkownika, co powoduje kod autoryzacji. Punkt końcowy tokenu jest następnie używany przez klienta do wymiany kodu tokenu dostępu, a także token odświeżania. Aplikacje internetowe są wymagane do przedstawienia własnych poświadczeń aplikacji do punktu końcowego tokenu, aby serwer autoryzacji mógł uwierzytelnić klienta.

Niejawne przyznanie OAuth2 jest wariantem innych dotacji autoryzacji. Umożliwia to klientowi uzyskanie tokenu dostępu (i id_token w przypadku korzystania z programu OpenId Connect) bezpośrednio z punktu końcowego autoryzacji bez kontaktu z punktem końcowym tokenu ani uwierzytelniania klienta. Ten wariant został zaprojektowany dla aplikacji opartych na języku JavaScript działających w przeglądarce internetowej: w oryginalnej specyfikacji OAuth2 tokeny są zwracane w fragmencie identyfikatora URI. Dzięki temu bity tokenu są dostępne dla kodu JavaScript w kliencie, ale gwarantuje to, że nie zostaną uwzględnione w przekierowaniach do serwera. W niejawnym przyznaniu OAuth2 punkt końcowy autoryzacji wystawia tokeny dostępu bezpośrednio do klienta przy użyciu podanego wcześniej identyfikatora URI przekierowania. Ma również zaletę wyeliminowania wszelkich wymagań dotyczących wywołań między źródłami, które są niezbędne, jeśli aplikacja JavaScript jest wymagana do skontaktowania się z punktem końcowym tokenu.

Ważną cechą niejawnego przyznawania OAuth2 jest fakt, że takie przepływy nigdy nie zwracają tokenów odświeżania do klienta. W następnej sekcji pokazano, jak to nie jest konieczne i w rzeczywistości byłoby problemem z zabezpieczeniami.

Odpowiednie scenariusze dla niejawnego przyznawania OAuth2

Specyfikacja OAuth2 deklaruje, że niejawne przyznanie zostało opracowane w celu włączenia aplikacji agenta użytkownika — czyli aplikacji JavaScript wykonywanych w przeglądarce. Charakterystyczną cechą takich aplikacji jest użycie kodu JavaScript do uzyskiwania dostępu do zasobów serwera (zazwyczaj internetowego interfejsu API) i odpowiedniego aktualizowania środowiska użytkownika aplikacji. Pomyśl o aplikacjach, takich jak Gmail lub Outlook Web Access: po wybraniu wiadomości ze skrzynki odbiorczej tylko panel wizualizacji wiadomości zmieni się, aby wyświetlić nowy wybór, podczas gdy reszta strony pozostaje niezmodyfikowana. Ta cecha jest sprzeczna z tradycyjnymi aplikacjami internetowymi opartymi na przekierowaniu, gdzie każda interakcja użytkownika powoduje powrót pełnej strony i pełną stronę renderowania nowej odpowiedzi serwera.

Aplikacje, które przyjmują podejście oparte na języku JavaScript do skrajności, są nazywane aplikacjami jednostronicowymi lub spA. Chodzi o to, że te aplikacje obsługują tylko początkową stronę HTML i skojarzony kod JavaScript, a wszystkie kolejne interakcje są sterowane przez wywołania internetowego interfejsu API wykonywane za pośrednictwem języka JavaScript. Jednak podejścia hybrydowe, w których aplikacja jest głównie sterowana po powrocie zwrotnym, ale wykonuje okazjonalne wywołania JS, nie są rzadkością — dyskusja na temat niejawnego użycia przepływu jest również odpowiednia dla tych metod.

Aplikacje oparte na przekierowaniu zwykle zabezpieczają swoje żądania za pośrednictwem plików cookie, jednak takie podejście nie działa również w przypadku aplikacji JavaScript. Pliki cookie działają tylko względem domeny, dla której zostały wygenerowane, podczas gdy wywołania języka JavaScript mogą być kierowane do innych domen. W rzeczywistości często zdarza się to: pomyśl o aplikacjach wywołujących usługę Microsoft interfejs Graph API, Interfejs API pakietu Office, interfejs API platformy Azure — wszystkie znajdujące się poza domeną, z której jest obsługiwana aplikacja. Rosnącym trendem dla aplikacji JavaScript jest brak zaplecza, który polega na 100% na interfejsach API sieci Web innych firm w celu zaimplementowania funkcji biznesowej.

Obecnie preferowaną metodą ochrony wywołań do internetowego interfejsu API jest użycie podejścia tokenu elementu nośnego OAuth2, w którym każde wywołanie jest dołączone do tokenu dostępu OAuth2. Internetowy interfejs API sprawdza token dostępu przychodzącego, a jeśli znajdzie go w niezbędnych zakresach, udziela dostępu do żądanej operacji. Niejawny przepływ zapewnia wygodny mechanizm dla aplikacji JavaScript w celu uzyskania tokenów dostępu dla internetowego interfejsu API, co zapewnia wiele zalet w odniesieniu do plików cookie:

  • Tokeny można niezawodnie uzyskać bez konieczności wywołań między źródłami — obowiązkowa rejestracja identyfikatora URI przekierowania, do którego tokeny są zwracane gwarancje, że tokeny nie są wypierane
  • Aplikacje Języka JavaScript mogą uzyskiwać dowolną liczbę tokenów dostępu dla jak największej liczby docelowych internetowych interfejsów API — bez ograniczeń dotyczących domen
  • Funkcje HTML5, takie jak sesja lub magazyn lokalny, zapewniają pełną kontrolę nad buforowaniem tokenów i zarządzaniem okresem istnienia, podczas gdy zarządzanie plikami cookie jest nieprzezroczyste dla aplikacji
  • Tokeny dostępu nie są podatne na ataki fałszowania żądań między lokacjami (CSRF)

Niejawny przepływ udzielania nie wystawia tokenów odświeżania, głównie ze względów bezpieczeństwa. Token odświeżania nie jest tak wąski, jak tokeny dostępu, udzielając znacznie większej mocy, co powoduje znacznie większe szkody w przypadku wycieku. W przepływie niejawnych tokeny są dostarczane w adresie URL, dlatego ryzyko przechwycenia jest wyższe niż w udzieleniu kodu autoryzacji.

Jednak aplikacja JavaScript ma do dyspozycji inny mechanizm odnawiania tokenów dostępu bez wielokrotnego monitowania użytkownika o poświadczenia. Aplikacja może używać ukrytego elementu iframe do wykonywania nowych żądań tokenu względem punktu końcowego autoryzacji Azure AD: o ile przeglądarka nadal ma aktywną sesję (odczyt: zawiera plik cookie sesji) względem domeny Azure AD, żądanie uwierzytelniania może być pomyślnie wykonane bez konieczności interakcji z użytkownikiem.

Ten model przyznaje aplikacji JavaScript możliwość niezależnego odnawiania tokenów dostępu, a nawet uzyskiwania nowych dla nowego interfejsu API (pod warunkiem, że użytkownik wcześniej wyraził na nie zgodę). Pozwala to uniknąć dodatkowego obciążenia związane z uzyskiwaniem, konserwem i ochroną artefaktu o wysokiej wartości, takiego jak token odświeżania. Artefakt, który umożliwia dyskretne odnawianie, plik cookie sesji Azure AD, jest zarządzany poza aplikacją. Inną zaletą tego podejścia jest to, że użytkownik może wylogować się z Azure AD, używając dowolnej aplikacji zalogowanej do Azure AD, uruchomionej na dowolnej karcie przeglądarki. Spowoduje to usunięcie pliku cookie sesji Azure AD, a aplikacja JavaScript automatycznie utraci możliwość odnawiania tokenów dla wylogowanego użytkownika.

Czy niejawne przyznanie jest odpowiednie dla mojej aplikacji?

Niejawne udzielanie stanowi większe ryzyko niż inne dotacje, a obszary, które należy zwrócić uwagę, są dobrze udokumentowane (na przykład niewłaściwe użycie tokenu dostępu do personifikacji właściciela zasobu w niejawnym przepływie i oauth 2.0 Threat Model i Zagadnienia dotyczące zabezpieczeń). Jednak wyższy profil ryzyka jest w dużej mierze spowodowany faktem, że jest przeznaczony do włączenia aplikacji, które wykonują aktywny kod, obsługiwane przez zasób zdalny do przeglądarki. Jeśli planujesz architekturę SPA, nie masz żadnych składników zaplecza lub zamierzasz wywołać internetowy interfejs API za pośrednictwem języka JavaScript, zaleca się użycie niejawnego przepływu na potrzeby pozyskiwania tokenów.

Jeśli aplikacja jest klientem natywnym, niejawny przepływ nie jest doskonałym rozwiązaniem. Brak pliku cookie sesji Azure AD w kontekście klienta natywnego pozbawia aplikację środków utrzymania długotrwałej sesji. Oznacza to, że aplikacja wielokrotnie monituje użytkownika podczas uzyskiwania tokenów dostępu dla nowych zasobów.

Jeśli tworzysz aplikację internetową zawierającą zaplecze i korzystasz z interfejsu API z jego kodu zaplecza, niejawny przepływ nie jest również dobrym rozwiązaniem. Inne dotacje dają ci znacznie większą moc. Na przykład udzielanie poświadczeń klienta OAuth2 zapewnia możliwość uzyskiwania tokenów, które odzwierciedlają uprawnienia przypisane do samej aplikacji, w przeciwieństwie do delegowania użytkowników. Oznacza to, że klient ma możliwość utrzymywania programowego dostępu do zasobów nawet wtedy, gdy użytkownik nie jest aktywnie zaangażowany w sesję itd. Nie tylko to, ale takie dotacje dają wyższe gwarancje bezpieczeństwa. Na przykład tokeny dostępu nigdy nie są przesyłane za pośrednictwem przeglądarki użytkownika, nie ryzykują zapisywania w historii przeglądarki itd. Aplikacja kliencka może również wykonywać silne uwierzytelnianie podczas żądania tokenu.

Następne kroki