A lecke végére meg tudod mondani, mire való az OAuth 2.0 és mire az OpenID Connect, fel tudod sorolni az OAuth szereplőit, le tudod írni az authorization code folyamat lépéseit, és el tudod különíteni a hozzáférési tokent az ID tokentől.
Miért nem adjuk át a jelszót?
A Kurzuspont szeretné a hallgató órarendjét egy külső naptárba menteni. Rossz megoldás lenne elkérni a hallgató naptárszolgáltatói jelszavát: a Kurzuspont akkor mindent megtehetne a hallgató nevében, és a jelszót el is árulhatná. A megoldás a delegált hozzáférés: a hallgató a naptárszolgáltatónál jelentkezik be, ott dönt arról, mit enged a Kurzuspontnak, és a Kurzuspont egy korlátozott jogosultságú tokent kap. A jelszó a naptárszolgáltatónál marad. Erre való az OAuth 2.0 keretrendszer.
flowchart LR
U[Hallgató] --> A[Kurzuspont]
A -->|hozzáférést kér| I[Engedélyező szolgáltató]
U -->|ott dönt| I
I -->|hozzáférési token| A
A -->|token a kérésben| N[Naptár API]
Az OAuth 2.0 szereplői
Az RFC 6749 négy szerepet különít el:
Szerep
Neve az RFC-ben
Példa
A hozzáférést megadó fél
resource owner (erőforrás-tulajdonos)
a hallgató
A hozzáférést kérő alkalmazás
client
a Kurzuspont
A tokent kiállító szerver
authorization server
a naptárszolgáltató engedélyező szervere
A védett erőforrást tároló szerver
resource server
a naptár API-ja
A szerepek szétválasztása azt segíti megérteni, hogy a token nem általános „be vagyok jelentkezve mindenhova” igazolás: egy meghatározott erőforrás elérésére szól, az adott engedély és érvényességi feltételek szerint.
Az authorization code folyamat
Az RFC 6749 szerint az authorization code (engedélykód) folyamat lépései:
A kliens a felhasználót az engedélyező szerverhez irányítja, megadva az azonosítóját, a kért hatókört (scope) és egy visszairányítási címet.
Az engedélyező szerver azonosítja a felhasználót, aki megadja vagy megtagadja a hozzáférést.
Ha megadja, a szerver visszairányítja a felhasználót a kliens címére egy engedélykóddal.
A kliens a kódot elküldi az engedélyező szerver token-végpontjának, és közben azonosítja magát.
A szerver ellenőrzi a kódot, és kiadja a hozzáférési tokent (és opcionálisan frissítő tokent).
sequenceDiagram
actor H as Hallgató
participant K as Kurzuspont (kliens)
participant E as Engedélyező szerver
participant N as Naptár API
H->>K: Órarend mentése a naptárba
K-->>H: Átirányítás az engedélyező szerverhez
H->>E: Bejelentkezik, engedélyt ad
E-->>H: Átirányítás a Kurzuspontra + engedélykód
H->>K: Engedélykód
K->>E: Kód beváltása (token kérése)
E-->>K: Hozzáférési token
K->>N: Kérés + token
N-->>K: Naptárművelet eredménye
Az ábra fogalmi, nem teljes protokollüzenet-sor. A kód a böngészőn keresztül, a token viszont közvetlenül a kliens és az engedélyező szerver között jut el, így a böngészőbe csak a rövid életű kód kerül.
PKCE: a kód elfogása elleni védelem
Az engedélykód átmehet olyan csatornán (visszairányítási cím), amelyet egy másik program elfoghat. A PKCE (Proof Key for Code Exchange, RFC 7636) ezt egy kérésenkénti titokkal védi: a kliens véletlen code_verifier-t készít, annak SHA-256 lenyomatából képzett code_challenge-et küld az első kérésben, a kód beváltásakor pedig az eredeti verifier-t. A szerver újraszámolja a lenyomatot, és összehasonlítja; ha eltér, elutasít. Az elfogott kód így verifier nélkül nem váltható be.
Kipróbáltuk az RFC 7636 példaértékeivel (Node.js crypto):
Az eredmény megegyezik az RFC-ben szereplő code_challenge értékkel. Az RFC 9700 (OAuth 2.0 biztonsági ajánlás) szerint a nyilvános kliensek (például mobil- és böngészős alkalmazások) számára a PKCE kötelező, a bizalmas klienseknek is ajánlott, és az S256 módszert kell használni. Ugyanez az RFC azt is mondja, hogy a kliensek ne használják az implicit folyamatot, amelyben a hozzáférési token közvetlenül az engedélyezési válaszban érkezik, mert az URL-ben, az előzményekben vagy a Referer fejlécben kiszivároghat.
Az OAuth 2.0 önmagában nem bejelentkezés
Az OAuth 2.0 azt mondja meg, hogyan kaphat egy kliens korlátozott hozzáférést egy erőforráshoz. Azt nem, hogy ki a felhasználó a kliens számára. Egy hozzáférési tokent ezért nem szabad automatikusan identitásigazolásként értelmezni. A token formája sem kötelezően JWT: lehet a kliens számára átláthatatlan érték.
OpenID Connect: identitás a kliensnek
Az OpenID Connect (OIDC) az OpenID Foundation specifikációja szerint egyszerű azonosítási réteg az OAuth 2.0 tetején: lehetővé teszi, hogy a kliens ellenőrizze, ki a felhasználó, az engedélyező szerver által végzett hitelesítés alapján. Legfontosabb eszköze az ID token (az ID az „identity”, azonosító rövidítése), amely egy JWT (7.3), és állításokat tartalmaz a felhasználó hitelesítéséről:
Állítás
Jelentése
iss (issuer)
Ki állította ki a tokent (egy https cím).
sub (subject)
A felhasználó azonosítója a kiállítónál, helyben egyedi és nem használódik újra.
aud (audience)
Kinek szól: tartalmaznia kell a kliens azonosítóját.
exp (expiration)
Meddig fogadható el.
Az ID tokent a kliensnek a saját céljára kell ellenőriznie (kiállító, közönség, lejárat, aláírás). Nem helyettesíti az API-nak szánt hozzáférési tokent.
flowchart TD
T[Mit akar az alkalmazás?] -->|külső API-t használni| O[OAuth 2.0: delegált hozzáférés]
T -->|a felhasználót bejelentkeztetni| I[OpenID Connect: identitás]
Az alkalmazás saját munkamenete külön életciklust is kaphat a külső szolgáltató bejelentkezésétől. Egy külső sikeres hitelesítés után a helyi alkalmazásnak továbbra is dönteni kell, milyen saját erőforrásokhoz ad hozzáférést a felismert felhasználónak. A külső azonosítás nem ad automatikus jogosultságot (7.4).
Végigvezetett példa: két feladat a Kurzuspontban
Feladat
Protokoll
Mit kap a Kurzuspont?
A hallgató az egyetemi azonosítójával lép be
OpenID Connect
ID tokent: ki a hallgató (sub), ki állította ki (iss).
Az órarend mentése a hallgató külső naptárába
OAuth 2.0
Hozzáférési tokent a naptár API-hoz, korlátozott hatókörrel.
Egy felhasználói élményben a két folyamat összekapcsolódhat („Belépés és naptár engedélyezése”), de fogalmilag eltér: az első azonosít, a második hozzáférést delegál. Mindkettőnél a Kurzuspont saját jogosultsági döntése (7.4) érvényben marad.
OAuth 2.0 és OpenID Connect
Célok
A lecke végére meg tudod mondani, mire való az OAuth 2.0 és mire az OpenID Connect, fel tudod sorolni az OAuth szereplőit, le tudod írni az authorization code folyamat lépéseit, és el tudod különíteni a hozzáférési tokent az ID tokentől.
Miért nem adjuk át a jelszót?
A Kurzuspont szeretné a hallgató órarendjét egy külső naptárba menteni. Rossz megoldás lenne elkérni a hallgató naptárszolgáltatói jelszavát: a Kurzuspont akkor mindent megtehetne a hallgató nevében, és a jelszót el is árulhatná. A megoldás a delegált hozzáférés: a hallgató a naptárszolgáltatónál jelentkezik be, ott dönt arról, mit enged a Kurzuspontnak, és a Kurzuspont egy korlátozott jogosultságú tokent kap. A jelszó a naptárszolgáltatónál marad. Erre való az OAuth 2.0 keretrendszer.
flowchart LR U[Hallgató] --> A[Kurzuspont] A -->|hozzáférést kér| I[Engedélyező szolgáltató] U -->|ott dönt| I I -->|hozzáférési token| A A -->|token a kérésben| N[Naptár API]Az OAuth 2.0 szereplői
Az RFC 6749 négy szerepet különít el:
A szerepek szétválasztása azt segíti megérteni, hogy a token nem általános „be vagyok jelentkezve mindenhova” igazolás: egy meghatározott erőforrás elérésére szól, az adott engedély és érvényességi feltételek szerint.
Az authorization code folyamat
Az RFC 6749 szerint az authorization code (engedélykód) folyamat lépései:
sequenceDiagram actor H as Hallgató participant K as Kurzuspont (kliens) participant E as Engedélyező szerver participant N as Naptár API H->>K: Órarend mentése a naptárba K-->>H: Átirányítás az engedélyező szerverhez H->>E: Bejelentkezik, engedélyt ad E-->>H: Átirányítás a Kurzuspontra + engedélykód H->>K: Engedélykód K->>E: Kód beváltása (token kérése) E-->>K: Hozzáférési token K->>N: Kérés + token N-->>K: Naptárművelet eredményeAz ábra fogalmi, nem teljes protokollüzenet-sor. A kód a böngészőn keresztül, a token viszont közvetlenül a kliens és az engedélyező szerver között jut el, így a böngészőbe csak a rövid életű kód kerül.
PKCE: a kód elfogása elleni védelem
Az engedélykód átmehet olyan csatornán (visszairányítási cím), amelyet egy másik program elfoghat. A PKCE (Proof Key for Code Exchange, RFC 7636) ezt egy kérésenkénti titokkal védi: a kliens véletlen
code_verifier-t készít, annak SHA-256 lenyomatából képzettcode_challenge-et küld az első kérésben, a kód beváltásakor pedig az eredetiverifier-t. A szerver újraszámolja a lenyomatot, és összehasonlítja; ha eltér, elutasít. Az elfogott kód így verifier nélkül nem váltható be.Kipróbáltuk az RFC 7636 példaértékeivel (Node.js
crypto):Az eredmény megegyezik az RFC-ben szereplő
code_challengeértékkel. Az RFC 9700 (OAuth 2.0 biztonsági ajánlás) szerint a nyilvános kliensek (például mobil- és böngészős alkalmazások) számára a PKCE kötelező, a bizalmas klienseknek is ajánlott, és azS256módszert kell használni. Ugyanez az RFC azt is mondja, hogy a kliensek ne használják az implicit folyamatot, amelyben a hozzáférési token közvetlenül az engedélyezési válaszban érkezik, mert az URL-ben, az előzményekben vagy a Referer fejlécben kiszivároghat.Az OAuth 2.0 önmagában nem bejelentkezés
Az OAuth 2.0 azt mondja meg, hogyan kaphat egy kliens korlátozott hozzáférést egy erőforráshoz. Azt nem, hogy ki a felhasználó a kliens számára. Egy hozzáférési tokent ezért nem szabad automatikusan identitásigazolásként értelmezni. A token formája sem kötelezően JWT: lehet a kliens számára átláthatatlan érték.
OpenID Connect: identitás a kliensnek
Az OpenID Connect (OIDC) az OpenID Foundation specifikációja szerint egyszerű azonosítási réteg az OAuth 2.0 tetején: lehetővé teszi, hogy a kliens ellenőrizze, ki a felhasználó, az engedélyező szerver által végzett hitelesítés alapján. Legfontosabb eszköze az ID token (az ID az „identity”, azonosító rövidítése), amely egy JWT (7.3), és állításokat tartalmaz a felhasználó hitelesítéséről:
iss(issuer)httpscím).sub(subject)aud(audience)exp(expiration)Az ID tokent a kliensnek a saját céljára kell ellenőriznie (kiállító, közönség, lejárat, aláírás). Nem helyettesíti az API-nak szánt hozzáférési tokent.
flowchart TD T[Mit akar az alkalmazás?] -->|külső API-t használni| O[OAuth 2.0: delegált hozzáférés] T -->|a felhasználót bejelentkeztetni| I[OpenID Connect: identitás]Az alkalmazás saját munkamenete külön életciklust is kaphat a külső szolgáltató bejelentkezésétől. Egy külső sikeres hitelesítés után a helyi alkalmazásnak továbbra is dönteni kell, milyen saját erőforrásokhoz ad hozzáférést a felismert felhasználónak. A külső azonosítás nem ad automatikus jogosultságot (7.4).
Végigvezetett példa: két feladat a Kurzuspontban
sub), ki állította ki (iss).Egy felhasználói élményben a két folyamat összekapcsolódhat („Belépés és naptár engedélyezése”), de fogalmilag eltér: az első azonosít, a második hozzáférést delegál. Mindkettőnél a Kurzuspont saját jogosultsági döntése (7.4) érvényben marad.
Gyakori tévhitek
Röviden
iss,sub,aud,exp).Ellenőrző kérdések
Tanulási források