Pred nekaj meseci sem implementiral strežnik OpenID Connect za upravljanje dostopa za stotine naših notranjih aplikacij. Od lastnega razvoja, primernega v manjšem obsegu, smo prešli na splošno sprejet standard. Dostop prek centralnega servisa bistveno poenostavi monotono poslovanje, zniža stroške izvajanja avtorizacij, omogoča, da najdete veliko že pripravljenih rešitev in si ne razbijate glave z razvojem novih. V tem članku bom govoril o tem prehodu in neravninah, ki smo jih uspeli premagati.

Dolgo nazaj ... Kjer se je vse začelo
Pred nekaj leti, ko je internih aplikacij postalo preveč za ročno upravljanje, smo napisali aplikacijo za nadzor dostopa znotraj podjetja. Šlo je za preprosto Rails aplikacijo, ki se je povezala z bazo podatkov o zaposlenih, kjer je bil nastavljen dostop do različnih funkcionalnosti. Hkrati smo lansirali prvi SSO, ki je temeljil na preverjanju žetonov s strani odjemalca in avtorizacijskega strežnika; žeton je bil posredovan v šifrirani obliki z več parametri in preverjen na avtorizacijskem strežniku. To ni bila najbolj priročna možnost, saj je morala vsaka interna aplikacija opisati precejšnjo plast logike, baze podatkov zaposlenih pa so bile popolnoma sinhronizirane s strežnikom za avtorizacijo.
Čez nekaj časa smo se odločili poenostaviti nalogo centralizirane avtorizacije. SSO je bil prenesen na bilančnik. S pomočjo OpenResty je bila v Luo dodana predloga, ki je preverjala žetone, vedela, kateri aplikaciji je namenjena zahteva, in lahko preverila, ali je tam dostop. Ta pristop je močno poenostavil nalogo nadzora dostopa do notranjih aplikacij – ni bilo več potrebe po opisovanju dodatne logike v kodi posamezne aplikacije. Posledično smo navzven zaprli promet, sama aplikacija pa o avtorizaciji ni vedela nič.
Vendar je en problem ostal nerešen. Kaj pa aplikacije, ki potrebujejo podatke o zaposlenih? Mogoče je bilo napisati API za avtorizacijsko storitev, vendar bi potem morali dodati dodatno logiko za vsako tako aplikacijo. Poleg tega smo se želeli znebiti odvisnosti od ene izmed naših samostojno napisanih aplikacij, ki je dodatno osredotočena na prevajanje v OpenSource, od našega internega avtorizacijskega strežnika. O tem vam bomo povedali kdaj drugič. Rešitev obeh težav je bil OAuth.
K splošno sprejetim standardom
OAuth je jasen, splošno sprejet avtorizacijski standard, a ker samo njegova funkcionalnost ni dovolj, je bil nemudoma upoštevan OpenID Connect (OIDC). Sam OIDC je tretja izvedba odprtega standarda za preverjanje pristnosti, ki se je razvil v nadnabor protokola OAuth 2.0 (Open Authorization Protocol). Ta rešitev rešuje problem pomanjkanja podatkov o končnem uporabniku, omogoča pa tudi menjavo avtorizatorja.
Vendar nismo izbrali določenega ponudnika in smo se odločili dodati integracijo z OIDC za naš obstoječi avtorizacijski strežnik. To odločitev je podprlo dejstvo, da je OIDC zelo prilagodljiv glede avtorizacije končnih uporabnikov. Tako je bilo mogoče implementirati podporo OIDC na vašem trenutnem avtorizacijskem strežniku.

Naša pot do implementacije lastnega strežnika OIDC
1) Podatke vnesite v zahtevano obliko
Za integracijo OIDC je potrebno trenutne uporabniške podatke spraviti v obliko, ki je razumljiva standardu. V OIDC se to imenuje zahtevki. Blagovne znamke so v bistvu končna polja v uporabniški bazi (ime, e-pošta, telefon itd.). obstaja , in vse, kar ni vključeno v ta seznam, se šteje po meri. Zato je prva točka, na katero morate biti pozorni, če želite izbrati obstoječega ponudnika OIDC, možnost priročnega prilagajanja novih žigov.
Skupina znamk je združena v naslednjo podmnožico – Obseg. Pri avtorizaciji se ne zahteva dostop do določenih oznak, ampak do obsegov, tudi če nekatere oznake iz obsega niso potrebne.
2) Izvedli potrebna nepovratna sredstva
Naslednji del integracije OIDC je izbira in implementacija vrst pooblastil, imenovanih odobritve. Nadaljnji scenarij interakcije med izbrano aplikacijo in avtorizacijskim strežnikom bo odvisen od izbrane odobritve. Približna shema za izbiro prave donacije je prikazana na spodnji sliki.

Za našo prvo aplikacijo smo uporabili najpogostejšo odobritev – avtorizacijsko kodo. Njegova razlika od drugih je, da je tristopenjski, tj. opravi dodatno testiranje. Najprej uporabnik zahteva avtorizacijsko dovoljenje, prejme žeton avtorizacijske kode, nato s tem žetonom, kot s potovalno karto, zahteva žeton dostopa. Vsa glavna interakcija tega avtorizacijskega scenarija temelji na preusmeritvah med aplikacijo in avtorizacijskim strežnikom. Več o tej subvenciji lahko preberete .
OAuth se drži koncepta, da morajo biti žetoni dostopa, prejeti po avtorizaciji, začasni in se po možnosti spremeniti v povprečju vsakih 10 minut. Dodelitev avtorizacijske kode je tristopenjska verifikacija s preusmeritvami, ki odkrito povedano ni najbolj prijetna naloga. Za rešitev te težave je na voljo še ena donacija - Refresh Token, ki smo jo prav tako uporabili. Tukaj je vse preprostejše. Pri preverjanju iz drugega granta se poleg glavnega dostopnega žetona izda še en - Refresh Token, ki ga je mogoče uporabiti le enkrat in je njegova življenjska doba praviloma bistveno daljša. S tem žetonom za osvežitev, ko se TTL (čas življenja) glavnega žetona dostopa konča, bo zahteva za nov žeton dostopa prispela na končno točko druge odobritve. Uporabljeni žeton za osvežitev se takoj ponastavi na nič. Takšno preverjanje je dvostopenjsko in se lahko izvaja v ozadju, neopazno za uporabnika.
3) Konfigurirani izhodni formati uporabniških podatkov
Ko so izbrana nepovratna sredstva izvedena, avtorizacija deluje, velja omeniti prejem podatkov o končnih uporabnikih. OIDC ima za to ločeno končno točko, kjer lahko zahtevate uporabniške podatke s svojim trenutnim dostopnim žetonom in če je posodobljen. In če se uporabniški podatki ne spreminjajo tako pogosto, vendar morate večkrat uporabiti trenutne, lahko pridete do rešitve, kot so žetoni JWT. Te žetone podpira tudi standard. Sam žeton JWT je sestavljen iz treh delov: glave (informacije o žetonu), obremenitve (vsi potrebni podatki) in podpisa (podpis, žeton je podpisan s strani strežnika in v prihodnje lahko preverite vir njegovega podpisa).
V izvedbi OIDC se žeton JWT imenuje id_token. Lahko ga zahtevate skupaj z običajnim dostopnim žetonom in vse, kar ostane, je preverjanje podpisa. V ta namen ima avtorizacijski strežnik ločeno končno točko s šopom javnih ključev v formatu . In ko smo že pri tem, velja omeniti, da obstaja še ena končna točka, ki temelji na standardu odraža trenutno konfiguracijo strežnika OIDC. Vsebuje vse naslove končnih točk (vključno z naslovom obroča javnih ključev, ki se uporablja za podpisovanje), podprte žige in obsege, uporabljene šifrirne algoritme, podprta dovoljenja itd.
Na primer v Googlu:
{
"issuer": "https://accounts.google.com",
"authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
"device_authorization_endpoint": "https://oauth2.googleapis.com/device/code",
"token_endpoint": "https://oauth2.googleapis.com/token",
"userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
"revocation_endpoint": "https://oauth2.googleapis.com/revoke",
"jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
"response_types_supported": [
"code",
"token",
"id_token",
"code token",
"code id_token",
"token id_token",
"code token id_token",
"none"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"scopes_supported": [
"openid",
"email",
"profile"
],
"token_endpoint_auth_methods_supported": [
"client_secret_post",
"client_secret_basic"
],
"claims_supported": [
"aud",
"email",
"email_verified",
"exp",
"family_name",
"given_name",
"iat",
"iss",
"locale",
"name",
"picture",
"sub"
],
"code_challenge_methods_supported": [
"plain",
"S256"
],
"grant_types_supported": [
"authorization_code",
"refresh_token",
"urn:ietf:params:oauth:grant-type:device_code",
"urn:ietf:params:oauth:grant-type:jwt-bearer"
]
}Tako lahko z uporabo id_token prenesete vse potrebne oznake v koristni token in se ne obrnete vsakič na avtorizacijski strežnik, da zahtevate uporabniške podatke. Slabost tega pristopa je, da spremembe uporabniških podatkov s strežnika ne pridejo takoj, ampak skupaj z novim dostopnim žetonom.
Rezultati implementacije
Tako smo po implementaciji lastnega OIDC strežnika in vzpostavitvi povezav z njim na aplikacijski strani rešili problem prenosa uporabniških informacij.
Ker je OIDC odprt standard, imamo zdaj možnost izbire obstoječega ponudnika ali implementacije strežnika. Preizkusili smo Keycloak, za katerega se je izkazalo, da ga je zelo enostavno konfigurirati; po nastavitvi in spreminjanju konfiguracije povezave na strani aplikacije je pripravljen za uporabo. Na strani aplikacije ostane le še sprememba konfiguracije povezave.
Govorimo o obstoječih rešitvah
V naši organizaciji smo kot prvi strežnik OIDC sestavili lastno implementacijo, ki smo jo po potrebi dopolnjevali. Po podrobnem pregledu drugih že pripravljenih rešitev lahko rečemo, da je to sporna točka. Odločitvi za uvedbo lastnega strežnika je botrovala zaskrbljenost ponudnikov glede pomanjkanja potrebnih funkcionalnosti, pa tudi prisotnost starega sistema, ki je vseboval različna pooblastila za nekatere storitve in že hranil kar nekaj podatkov o zaposlenih . Vendar pa v že pripravljenih izvedbah obstajajo ugodnosti za integracijo. Na primer, Keycloak ima svoj sistem za upravljanje uporabnikov in podatki so shranjeni neposredno v njem, in preselitev vaših uporabnikov tja ne bo težavna. V ta namen ima Keycloak API, ki vam bo omogočil, da v celoti izvedete vsa potrebna dejanja prenosa.
Drug primer certificirane, po mojem mnenju zanimive izvedbe je Ory Hydra. Zanimiva je, ker je sestavljena iz različnih komponent. Za integracijo boste morali svojo storitev upravljanja uporabnikov povezati z njihovo avtorizacijsko storitvijo in po potrebi razširiti.
Keycloak in Ory Hydra nista edini že pripravljeni rešitvi. Najbolje je izbrati izvedbo, ki jo je potrdila OpenID Foundation. Te rešitve imajo običajno značko certifikata OpenID.

Ne pozabite tudi na obstoječe plačljive ponudnike, če ne želite obdržati svojega strežnika OIDC. Danes obstaja veliko dobrih možnosti.
Kaj je naslednje?
V bližnji prihodnosti bomo na drugačen način zaprli promet internim storitvam. Načrtujemo selitev naše trenutne enotne prijave na uravnoteženje z uporabo OpenResty na proxy, ki temelji na OAuth. Tukaj je tudi veliko že pripravljenih rešitev, na primer:
Dodatni materiali
– dobra storitev za preverjanje žetonov JWT
— seznam certificiranih izvedb OIDC
Vir: www.habr.com
