Podstawy OAuth2

effectivedev.pl 1 rok temu

OAuth2 to protokół uwierzytelniania, który pozwala na zdecydowanie więcej niż standardowe logowanie się użytkownika do aplikacji dzięki loginu i hasła. Prawdę mówiąc, to tylko jedna z wielu opcji.

Główną zaletą OAuth2 jest możliwość przekazywania uprawnień do zasobów. Jedna aplikacja, do której użytkownik się zaloguje, ma możliwość udzielenia innej aplikacji poświadczeń zalogowanego użytkownika, bez przekazywania do niej jakichkolwiek wrażliwych informacji.

Na pewno kojarzysz ten mechanizm z sieci. Wiele stron pozwala Ci się zalogować dzięki Google czy Facebooka, pod spodem działa właśnie OAuth2.

Authorization Flow

Protokół opiera się o tzw. Authorization Flow, co można przetłumaczyć na Proces uwierzytelniania. Podstawowa specyfikacja definiuje 4 takie procesy:

  • Resource Owner Password Credentials
  • Authorization Code
  • Client Credentials
  • Implicit

Z czego Implicit oraz Client Credentials są przeznaczone dla specjalnego typu klientów:

  • Implicit – dla Single-page Web App
  • Client Credentials – dla komunikacji usług bez udziału człowieka

Pozostałe procesy służą albo do uwierzytelnienia użytkownika, albo do przekazania uprawnień stronie trzeciej (Authorization Code).

Resource Owner Password Credentials

Ten proces wymaga, aby aplikacja kliencka (która przyjmuje nasze credentiale) była wysoce zaufana. Co tak naprawdę znaczy, iż to ma być nasz frontend do naszego systemu.

Proces wygląda tak:

  1. Aplikacja (client) prosi użytkownika o jego login i hasło (na przykład).
  2. Aplikacja wysyła credentiale użytkownika do serwera autoryzacyjnego, który weryfikuje dane i zwraca access token oraz opcjonalnie refresh token.
  3. Aplikacja wykorzystuje access token. aby otrzymać dostęp do zasobów na serwerze (resource server)

Authorization Code

W tym procesie, aplikacja (client) musi być w stanie wejść w interakcje z użytkownikiem.

Wygląda to tak:

  1. Aplikacja (client) przygotowuje link do serwera autoryzacyjnego i przesyła go użytkownikowi. Link prezentuje wszelkie informacje pozwalające serwerowi na zidentyfikowanie i odpowiedzenie użytkownikowi.
  2. Użytkownik wprowadza swoje credentiale (np. login i hasło)
  3. Credentiale są wysłane do serwera autoryzacyjnego
  4. Serwer weryfikuje credentiale i przekierowuje użytkownika z powrotem do aplikacji, dołączając kod autoryzacyjny.
  5. Aplikacja kontaktuje się z serwerem autoryzacyjnym, potwierdza swoja tożsamość i wymienia kod autoryzacyjny na access token oraz opcjonalnie refresh token
  6. Aplikacja wykorzystuje access token, aby otrzymać dostęp do zasobów na serwerze (resource serwer).

Ten proces możesz też spotkać w wersji rozszerzonej o PKCE, czyli Proof Key for Code Exchange. Jest to wersja, która zwiększa poziom bezpieczeństwa, pozwalając jasno zweryfikować, czy aplikacja kliencka, która zainicjowała cały proces autoryzacyjny, to jest ta sama aplikacja, która wykorzystuje wydany kod autoryzacyjny w celu pozyskania access tokena.

Client Credentials

Kolejny prorces, tym razem nie dla ludzi. Zamiast człowieka mamy tutaj maszynę, usługę, cokolwiek co ma zaszyte w swojej konfiguracje sekrety:

  • client ID – identyikator, odpowiednik loginu.
  • client secret – sekret, będący odpowiednikiem hasła.

Sam proces wygląda bardzo prosto:

  1. Aplikacja wysyła swoje credentiale do serwera autoryzacyjnego, który weryfikuje dane i zwraca access token oraz opcjonalnie refresh token.
  2. Aplikacja wykorzystuje access token. aby otrzymać dostęp do zasobów na serwerze (resource server)

To jest model, który zwykle jest używany w wewnętrznej komunikacji systemu, pomiędzy jego komponentami (mikroserwisami).

Implicit

Ten proces jest trochę dziwny. Co więcej, nie zaleca się już go używać, ponieważ powstał on tylko po to, aby pogodzić pewne ograniczenia techniczne (brak możliwości wywołania innej domeny z JS) z potrzebą zapewnienia bezpieczeństwa. Aktualnie, przeglądarki już nie mają tego ograniczenia, co sprawia, iż bez przeszkód można użyć bezpieczniejszego rozwiązania, czyli np. Authorization Code (z PKCE).

Sam proces wygląda bardzo podobnie do Authorization Code:

  1. Aplikacja (client) przygotowuje link do serwera autoryzacyjnego i przesyła go użytkownikowi. Link prezentuje wszelkie informacje pozwalające serwerowi na zidentyfikowanie i odpowiedzenie użytkownikowi.
  2. Użytkownik wprowadza swoje credentiale (np. login i hasło)
  3. Credentiale są wysłane do serwera autoryzacyjnego
  4. Serwer weryfikuje credentiale i wydaje access token oraz opcjonalnie refresh token
  5. Aplikacja wykorzystuje access token, aby otrzymać dostęp do zasobów na serwerze (resource serwer).

Jak widzisz, główna różnica jest taka, iż po potwierdzeniu tożsamości, od razu zwracane są tokeny.

Tokeny

Na koniec jeszcze kilka słów o tokenach. Zazwyczaj, są tutaj używane tokeny JWT, które składają się z trzech elementów:

  • header – nagłówek, zawierający informacje o użytych w podpisie algorytmach.
  • payload – wszelkie informacje jakie niesie ze sobą token.
  • signature – podpis, potwierdzający, iż token nie został zmieniony.

Dwa pierwsze elementy to po prostu JSON, zakodowany w base64, natomiast podpis, to w zależności od algorytmu, wygenerowany ciąg znaków (np. kryptograficznie) w oparciu o header i payload.

Taka konstrukcja pozwala mieć dosyć wysokie zaufanie do przekazanych w nim informacji.
Co więcej, w tokenie zaszyte są też informacje (claim) takie jak:

  • exp – czyli do kiedy ten token jest istotny (należy go odświeżyć przed upływem tego czasu, używając refresh tokena).
  • iss – przez kogo token został wydany.
  • sub – dla kogo token został wydany.

Źródla


Ten artykuł znalazł się w Mailingu EffectiveDev

Wydanie #24

Podstawy OAuth2

  • Podstawy OAuth2
    Czyli jak zabezpieczyć Twój system
  • Targeted Event-Carried State Transfer
    Czyli wysoki coupling z Eventami w tle
  • SOLID: Open-Closed Principle
    Czyli o co tak naprawdę tutaj chodzi
  • 60 stron o Event-Driven Architecture
    Czyli co interesującego na Twitterze

Dołącz TUTAJ
Co tydzień, podobne artykuły otrzymasz prosto do swojej skrzynki mailowej!

Idź do oryginalnego materiału