OpenID Connect: autorizacija internih aplikacija od prilagođenih do standardnih

Prije nekoliko mjeseci implementirao sam OpenID Connect server za upravljanje pristupom stotinama naših internih aplikacija. Iz vlastitog razvoja, pogodnog u manjem obimu, prešli smo na općeprihvaćeni standard. Pristup preko centralnog servisa uvelike pojednostavljuje monotone operacije, smanjuje troškove implementacije autorizacija, omogućava vam da pronađete mnoga gotova rješenja i da se ne mučite kada razvijate nova. U ovom članku ću govoriti o ovoj tranziciji i neravninama koje smo uspjeli popuniti.

OpenID Connect: autorizacija internih aplikacija od prilagođenih do standardnih

Davno... Kako je sve počelo

Prije nekoliko godina, kada je bilo previše internih aplikacija za ručnu kontrolu, napisali smo aplikaciju za kontrolu pristupa unutar kompanije. Bila je to jednostavna Rails aplikacija koja se povezivala sa bazom podataka sa podacima o zaposlenima, gdje je konfigurisan pristup raznim funkcionalnostima. Istovremeno smo podigli i prvi SSO koji se bazirao na verifikaciji tokena sa strane klijenta i autorizacionog servera, token je prenet u šifrovanom obliku sa nekoliko parametara i verifikovan na serveru za autorizaciju. Ovo nije bila najpogodnija opcija, jer je svaka interna aplikacija morala opisati značajan sloj logike, a baze podataka zaposlenika su bile u potpunosti sinhronizirane sa autorizacijskim serverom.

Nakon nekog vremena, odlučili smo da pojednostavimo zadatak centralizirane autorizacije. SSO je prebačen u bilans. Uz pomoć OpenResty-a, u Lua je dodan predložak koji provjerava tokene, zna na koju aplikaciju zahtjev ide i može provjeriti postoji li pristup tamo. Ovaj pristup je uvelike pojednostavio zadatak kontrole pristupa internim aplikacijama – u kodu svake aplikacije više nije bilo potrebno opisivati ​​dodatnu logiku. Kao rezultat toga, zatvorili smo promet eksterno, a sama aplikacija nije znala ništa o autorizaciji.

Međutim, jedan problem je ostao neriješen. Šta je sa aplikacijama kojima su potrebne informacije o zaposlenima? Bilo je moguće napisati API za servis autorizacije, ali tada biste morali dodati dodatnu logiku za svaku takvu aplikaciju. Osim toga, željeli smo da se riješimo ovisnosti o jednoj od naših samopisnih aplikacija, koja će kasnije biti prevedena u OpenSource, na našem internom serveru za autorizaciju. Pričaćemo o tome neki drugi put. Rješenje za oba problema bio je OAuth.

prema zajedničkim standardima

OAuth je razumljiv, općeprihvaćen standard autorizacije, ali kako samo njegova funkcionalnost nije dovoljna, odmah su počeli razmatrati OpenID Connect (OIDC). Sam OIDC je treća implementacija standarda otvorene provjere autentičnosti, koji je prešao u dodatak preko OAuth 2.0 protokola (otvoreni protokol za autorizaciju). Ovo rješenje zatvara problem nedostatka podataka o krajnjem korisniku, a omogućava i promjenu provajdera autorizacije.

Međutim, nismo odabrali određenog provajdera i odlučili smo dodati integraciju sa OIDC-om za naš postojeći autorizacijski server. U prilog ovoj odluci išla je činjenica da je OIDC veoma fleksibilan u pogledu autorizacije krajnjeg korisnika. Tako je bilo moguće implementirati OIDC podršku na vašem trenutnom autorizacijskom serveru.

OpenID Connect: autorizacija internih aplikacija od prilagođenih do standardnih

Naš način implementacije vlastitog OIDC servera

1) Doveo podatke u željeni oblik

Za integraciju OIDC-a, potrebno je trenutne korisničke podatke dovesti u formu razumljivu standardu. U OIDC-u se to zove potraživanja. Zahtjevi su u suštini konačna polja u korisničkoj bazi podataka (ime, email, telefon, itd.). Postoji standardna lista maraka, a sve što nije uključeno u ovu listu smatra se prilagođenim. Stoga, prva stvar na koju morate obratiti pažnju ako želite da odaberete postojećeg OIDC provajdera je mogućnost pogodnog prilagođavanja novih brendova.

Grupa obeležja je kombinovana u sledeći podskup - Obim. Prilikom autorizacije traži se pristup ne određenim markama, već obimima, čak i ako neki od brendova iz opsega nisu potrebni.

2) Realizovani neophodni grantovi

Sljedeći dio integracije OIDC-a je odabir i implementacija tipova autorizacije, tzv. grantova. Dalji scenarij interakcije između odabrane aplikacije i autorizacijskog servera ovisit će o odabranoj dodjeli. Primjer sheme za odabir pravog granta prikazan je na donjoj slici.

OpenID Connect: autorizacija internih aplikacija od prilagođenih do standardnih

Za našu prvu aplikaciju koristili smo najčešći grant, autorizacijski kod. Njegova razlika od ostalih je u tome što je trostepena, tj. je na dodatnom testiranju. Prvo korisnik podnese zahtjev za dozvolu autorizacije, dobije token - Autorizacijski kod, zatim sa ovim tokenom, kao sa kartom za putovanje, traži pristupni token. Sva glavna interakcija ove autorizacijske skripte zasniva se na preusmjeravanju između aplikacije i autorizacionog servera. Više o ovom grantu možete pročitati ovdje.

OAuth se pridržava koncepta da bi tokeni za pristup dobijeni nakon autorizacije trebali biti privremeni i trebali bi se mijenjati, po mogućnosti svakih 10 minuta u prosjeku. Dodjela koda autorizacije je provjera u tri koraka putem preusmjeravanja, svakih 10 minuta okretanje takvog koraka, iskreno, nije najprijatniji zadatak za oči. Za rješavanje ovog problema postoji još jedan grant - Refresh Token, koji smo također koristili u našoj zemlji. Ovdje je sve lakše. Prilikom verifikacije iz drugog granta, pored glavnog tokena za pristup, izdaje se još jedan - Refresh Token, koji se može koristiti samo jednom i životni vijek mu je obično mnogo duži. Sa ovim tokenom za osvježavanje, kada se završi TTL (vrijeme života) glavnog tokena za pristup, zahtjev za novim tokenom pristupa će doći do krajnje točke drugog odobrenja. Korišteni token za osvježavanje se odmah resetuje na nulu. Ova provjera je u dva koraka i može se izvršiti u pozadini, neprimjetno za korisnika.

3) Postavite prilagođene formate za izlaz podataka

Nakon implementacije odabranih grantova, autorizacija proradi, vrijedi spomenuti dobivanje podataka o krajnjem korisniku. OIDC ima zasebnu krajnju tačku za ovo, gdje možete zatražiti korisničke podatke sa svojim trenutnim pristupnim tokenom i ako je ažuriran. A ako se podaci korisnika ne mijenjaju tako često, a potrebno je više puta pratiti trenutne, možete doći do takvog rješenja kao što su JWT tokeni. Ovi tokeni su također podržani standardom. Sam JWT token se sastoji od tri dijela: zaglavlja (informacije o tokenu), tereta (svi potrebni podaci) i potpisa (potpis, token potpisuje server i kasnije možete provjeriti izvor njegovog potpisa).

U OIDC implementaciji, JWT token se zove id_token. Može se zatražiti zajedno sa redovnim tokenom za pristup i sve što preostaje je provjeriti potpis. Autorizacijski server ima zasebnu krajnju tačku za ovo sa gomilom javnih ključeva u formatu J.W.K.. A kad smo već kod ovoga, vrijedi spomenuti da postoji još jedna krajnja tačka, koja se zasniva na standardu RFC5785 odražava trenutnu konfiguraciju OIDC servera. Sadrži sve adrese krajnjih tačaka (uključujući adresu prstena javnog ključa koji se koristi za potpisivanje), podržane brendove i opsege, korištene algoritme šifriranja, podržane grantove itd.

Na primjer na Googleu:

{
 "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"
 ]
}

Dakle, koristeći id_token, možete prenijeti sve potrebne oznake na nosivost tokena i ne kontaktirati autorizacijski server svaki put da biste zatražili korisničke podatke. Nedostatak ovakvog pristupa je što promjena korisničkih podataka sa servera ne dolazi odmah, već zajedno sa novim tokenom za pristup.

Rezultati implementacije

Dakle, nakon implementacije vlastitog OIDC servera i konfigurisanja konekcija sa njim na strani aplikacije, riješili smo problem prijenosa informacija o korisnicima.
Pošto je OIDC otvoreni standard, imamo mogućnost izbora postojećeg provajdera ili implementacije servera. Isprobali smo Keycloak, koji se pokazao vrlo pogodnim za konfiguraciju, nakon postavljanja i promjene konfiguracije veze na strani aplikacije, spreman je za rad. Što se tiče aplikacije, sve što ostaje je promijeniti konfiguracije veze.

Govorimo o postojećim rješenjima

Unutar naše organizacije, kao prvi OIDC server, sklopili smo vlastitu implementaciju, koja je po potrebi dopunjavana. Nakon detaljnog pregleda ostalih gotovih rješenja, možemo reći da je ovo sporno. U prilog odluke o implementaciji vlastitog servera izrazile su se zabrinutosti od strane provajdera u nedostatku potrebne funkcionalnosti, kao i prisutnost starog sistema u kojem su postojala različita prilagođena ovlaštenja za neke servise i dosta podataka o zaposlenima je već pohranjeno. Međutim, u gotovim implementacijama postoje pogodnosti za integraciju. Na primjer, Keycloak ima svoj vlastiti sistem za upravljanje korisnicima i podaci se pohranjuju direktno u njega i neće biti teško prestići svoje korisnike tamo. Da biste to učinili, Keycloak ima API koji će vam omogućiti da u potpunosti izvršite sve potrebne radnje prijenosa.

Još jedan primjer certificirane, zanimljive, po mom mišljenju, implementacije je Ory Hydra. Zanimljiva je jer se sastoji od različitih komponenti. Za integraciju, morat ćete povezati svoju uslugu upravljanja korisnicima s njihovom uslugom autorizacije i proširiti po potrebi.

Keycloak i Ory Hydra nisu jedina gotova rješenja. Najbolje je odabrati implementaciju certificiranu od strane OpenID Foundation. Ova rješenja obično imaju značku OpenID Certification.

OpenID Connect: autorizacija internih aplikacija od prilagođenih do standardnih

Također ne zaboravite na postojeće plaćene provajdere ako ne želite zadržati svoj OIDC server. Danas postoji mnogo dobrih opcija.

Šta sledi

U bliskoj budućnosti ćemo na drugačiji način zatvoriti saobraćaj prema internim servisima. Planiramo da prenesemo naš trenutni SSO na balanser koristeći OpenResty na proxy baziran na OAuth-u. Ovdje već postoje mnoga gotova rješenja, na primjer:
github.com/bitly/oauth2_proxy
github.com/ory/oathkeeper
github.com/keycloak/keycloak-gatekeeper

Dodatni materijali

jwt.io – dobar servis za validaciju JWT tokena
openid.net/developers/certified - lista certificiranih implementacija OIDC-a

izvor: www.habr.com

Dodajte komentar