OAuth2 to protokół uwierzytelniania, który pozwala na zdecydowanie więcej niż standardowe logowanie się użytkownika do aplikacji za pomocą 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ć za pomocą 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 AppClient 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, że to ma być nasz frontend do naszego systemu.
Proces wygląda tak:
- Aplikacja (client) prosi użytkownika o jego login i hasło (na przykład).
- Aplikacja wysyła credentiale użytkownika do serwera autoryzacyjnego, który weryfikuje dane i zwraca
access token
oraz opcjonalnierefresh token
. - 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:
- 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.
- Użytkownik wprowadza swoje credentiale (np. login i hasło)
- Credentiale są wysłane do serwera autoryzacyjnego
- Serwer weryfikuje credentiale i przekierowuje użytkownika z powrotem do aplikacji, dołączając kod autoryzacyjny.
- Aplikacja kontaktuje się z serwerem autoryzacyjnym, potwierdza swoja tożsamość i wymienia kod autoryzacyjny na
access token
oraz opcjonalnierefresh token
- 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:
- Aplikacja wysyła swoje credentiale do serwera autoryzacyjnego, który weryfikuje dane i zwraca
access token
oraz opcjonalnierefresh token
. - Aplikacja wykorzystuje
access token
. aby otrzymać dostęp do zasobów na serwerze (resource server
)
To jest model, który zazwyczaj 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, że 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:
- 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.
- Użytkownik wprowadza swoje credentiale (np. login i hasło)
- Credentiale są wysłane do serwera autoryzacyjnego
- Serwer weryfikuje credentiale i wydaje
access token
oraz opcjonalnierefresh token
- Aplikacja wykorzystuje
access token
, aby otrzymać dostęp do zasobów na serwerze (resource serwer
).
Jak widzisz, główna różnica jest taka, że 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, że 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 ważny (należy go odświeżyć przed upływem tego czasu, używającrefresh 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 ciekawego na Twitterze
Dołącz TUTAJ
Co tydzień, podobne artykuły otrzymasz prosto do swojej skrzynki mailowej!
Dodaj komentarz