OpenID Connect: awtorisasyon ng mga panloob na application mula sa custom hanggang sa karaniwan

Ilang buwan na ang nakalipas, nagpapatupad ako ng OpenID Connect server upang pamahalaan ang access para sa daan-daang aming mga panloob na application. Mula sa aming sariling mga pag-unlad, na maginhawa sa isang mas maliit na sukat, kami ay lumipat sa isang karaniwang tinatanggap na pamantayan. Ang pag-access sa pamamagitan ng sentral na serbisyo ay lubos na nagpapadali sa mga monotonous na operasyon, binabawasan ang gastos ng pagpapatupad ng mga pahintulot, nagbibigay-daan sa iyo na makahanap ng maraming handa na solusyon at hindi masira ang iyong mga utak kapag bumubuo ng mga bago. Sa artikulong ito, pag-uusapan ko ang tungkol sa paglipat na ito at ang mga bump na nagawa naming punan.

OpenID Connect: awtorisasyon ng mga panloob na application mula sa custom hanggang sa karaniwan

A long time ago... Kung paano nagsimula ang lahat

Ilang taon na ang nakalilipas, nang napakaraming panloob na aplikasyon para sa manu-manong kontrol, sumulat kami ng aplikasyon para makontrol ang pag-access sa loob ng kumpanya. Ito ay isang simpleng application ng Rails na nakakonekta sa isang database na may impormasyon tungkol sa mga empleyado, kung saan na-configure ang access sa iba't ibang functionality. Kasabay nito, itinaas namin ang unang SSO, na batay sa pag-verify ng mga token mula sa gilid ng kliyente at sa server ng pahintulot, ang token ay ipinadala sa naka-encrypt na form na may ilang mga parameter at na-verify sa server ng pahintulot. Hindi ito ang pinaka-maginhawang opsyon, dahil ang bawat panloob na aplikasyon ay kailangang ilarawan ang isang malaking layer ng lohika, at ang mga database ng empleyado ay ganap na naka-synchronize sa server ng pahintulot.

Pagkaraan ng ilang oras, nagpasya kaming gawing simple ang gawain ng sentralisadong awtorisasyon. Ang SSO ay inilipat sa balancer. Sa tulong ng OpenResty, isang template ang idinagdag sa Lua na nagsuri ng mga token, alam kung aling application ang pupuntahan ng kahilingan, at maaaring suriin kung mayroong access doon. Ang diskarte na ito ay lubos na pinasimple ang gawain ng pagkontrol ng pag-access sa mga panloob na aplikasyon - sa code ng bawat aplikasyon, hindi na kinakailangan upang ilarawan ang karagdagang lohika. Bilang resulta, isinara namin ang trapiko sa labas, at ang application mismo ay walang alam tungkol sa pahintulot.

Gayunpaman, isang problema ang nanatiling hindi nalutas. Paano ang mga application na nangangailangan ng impormasyon tungkol sa mga empleyado? Posibleng magsulat ng API para sa serbisyo ng awtorisasyon, ngunit pagkatapos ay kailangan mong magdagdag ng karagdagang lohika para sa bawat naturang aplikasyon. Bilang karagdagan, gusto naming alisin ang pag-asa sa isa sa aming mga self-written na application, na sa kalaunan ay isasalin sa OpenSource, sa aming internal na server ng pahintulot. Pag-uusapan natin ito sa ibang pagkakataon. Ang solusyon sa parehong problema ay OAuth.

sa mga karaniwang pamantayan

Ang OAuth ay isang nauunawaan, karaniwang tinatanggap na pamantayan ng pahintulot, ngunit dahil hindi sapat ang functionality nito, agad nilang sinimulan na isaalang-alang ang OpenID Connect (OIDC). Ang OIDC mismo ay ang ikatlong pagpapatupad ng open authentication standard, na dumaloy sa isang add-on sa OAuth 2.0 protocol (isang open authorization protocol). Isinasara ng solusyong ito ang problema ng kakulangan ng data tungkol sa end user, at ginagawang posible na baguhin ang provider ng awtorisasyon.

Gayunpaman, hindi kami pumili ng isang partikular na provider at nagpasya na magdagdag ng pagsasama sa OIDC para sa aming umiiral na server ng pahintulot. Pabor sa desisyong ito ay ang katotohanan na ang OIDC ay napaka-flexible sa mga tuntunin ng pahintulot ng end user. Kaya, naging posible na ipatupad ang suporta ng OIDC sa iyong kasalukuyang server ng pahintulot.

OpenID Connect: awtorisasyon ng mga panloob na application mula sa custom hanggang sa karaniwan

Ang aming paraan ng pagpapatupad ng aming sariling OIDC server

1) Dinala ang data sa nais na form

Upang maisama ang OIDC, kinakailangan na dalhin ang kasalukuyang data ng gumagamit sa isang form na naiintindihan ng pamantayan. Sa OIDC ito ay tinatawag na Claims. Ang mga claim ay mahalagang mga huling field sa database ng user (pangalan, email, telepono, atbp.). Umiiral karaniwang listahan ng mga selyo, at lahat ng hindi kasama sa listahang ito ay itinuturing na custom. Samakatuwid, ang unang punto na kailangan mong bigyang pansin kung gusto mong pumili ng isang umiiral na provider ng OIDC ay ang posibilidad ng maginhawang pagpapasadya ng mga bagong tatak.

Ang pangkat ng mga tanda ay pinagsama sa sumusunod na subset - Saklaw. Sa panahon ng pahintulot, hinihiling ang pag-access hindi sa mga partikular na brand, ngunit sa mga saklaw, kahit na hindi kailangan ang ilan sa mga brand mula sa saklaw.

2) Ipinatupad ang mga kinakailangang gawad

Ang susunod na bahagi ng pagsasama-sama ng OIDC ay ang pagpili at pagpapatupad ng mga uri ng awtorisasyon, ang tinatawag na mga gawad. Ang karagdagang senaryo ng pakikipag-ugnayan sa pagitan ng napiling aplikasyon at ng server ng pahintulot ay depende sa napiling grant. Ang isang huwarang pamamaraan para sa pagpili ng tamang grant ay ipinapakita sa figure sa ibaba.

OpenID Connect: awtorisasyon ng mga panloob na application mula sa custom hanggang sa karaniwan

Para sa aming unang aplikasyon, ginamit namin ang pinakakaraniwang grant, ang Authorization Code. Ang pagkakaiba nito sa iba ay ito ay isang tatlong hakbang, i.e. ay sumasailalim sa karagdagang pagsubok. Una, humiling ang user para sa pahintulot ng awtorisasyon, tumatanggap ng token - Authorization Code, pagkatapos ay sa token na ito, na parang may ticket para sa paglalakbay, humihiling ng access token. Ang lahat ng pangunahing interaksyon ng authorization script na ito ay batay sa mga pag-redirect sa pagitan ng application at ng authorization server. Maaari kang magbasa nang higit pa tungkol sa grant na ito dito.

Ang OAuth ay sumusunod sa konsepto na ang mga token sa pag-access na nakuha pagkatapos ng pahintulot ay dapat pansamantala at dapat magbago, mas mabuti tuwing 10 minuto sa average. Ang pagbibigay ng Authorization Code ay isang tatlong-hakbang na pag-verify sa pamamagitan ng mga pag-redirect, bawat 10 minuto upang i-on ang ganoong hakbang, sa totoo lang, ay hindi ang pinaka-kaaya-ayang gawain para sa mga mata. Para masolusyunan ang problemang ito, may isa pang grant - Refresh Token, na ginamit din natin sa ating bansa. Mas madali ang lahat dito. Sa panahon ng pag-verify mula sa isa pang grant, bilang karagdagan sa pangunahing token ng pag-access, isa pa ang ibinibigay - Refresh Token, na maaaring magamit nang isang beses lamang at ang buhay nito ay karaniwang mas matagal. Sa Refresh Token na ito, kapag natapos na ang TTL (Time to Live) ng pangunahing access token, ang kahilingan para sa isang bagong access token ay darating sa endpoint ng isa pang grant. Ang ginamit na Refresh Token ay agad na ni-reset sa zero. Ang pagsusuring ito ay dalawang hakbang at maaaring isagawa sa background, nang hindi mahahalata ng user.

3) I-set up ang mga custom na format ng output ng data

Matapos maipatupad ang mga napiling gawad, gumagana ang pahintulot, sulit na banggitin ang pagkuha ng data tungkol sa end user. Ang OIDC ay may hiwalay na endpoint para dito, kung saan maaari kang humiling ng data ng user gamit ang iyong kasalukuyang access token at kung ito ay napapanahon. At kung ang data ng gumagamit ay hindi nagbabago nang madalas, at kailangan mong sundan ang mga kasalukuyan nang maraming beses, maaari kang makarating sa isang solusyon bilang mga token ng JWT. Ang mga token na ito ay sinusuportahan din ng pamantayan. Ang mismong JWT token ay binubuo ng tatlong bahagi: header (impormasyon tungkol sa token), payload (anumang kinakailangang data) at lagda (pirma, ang token ay nilagdaan ng server at maaari mong suriin sa ibang pagkakataon ang pinagmulan ng lagda nito).

Sa pagpapatupad ng OIDC, ang JWT token ay tinatawag na id_token. Maaari itong hilingin kasama ng isang regular na token ng pag-access at ang natitira na lang ay i-verify ang lagda. Ang authorization server ay may hiwalay na endpoint para dito na may isang grupo ng mga pampublikong key sa format JWK. At pagsasalita tungkol dito, ito ay nagkakahalaga ng pagbanggit na mayroong isa pang endpoint, na, batay sa pamantayan RFC5785 sumasalamin sa kasalukuyang configuration ng OIDC server. Naglalaman ito ng lahat ng endpoint address (kabilang ang address ng pampublikong key ring na ginamit para sa pagpirma), mga sinusuportahang brand at saklaw, ginamit na mga algorithm ng pag-encrypt, mga suportadong grant, atbp.

Halimbawa sa Google:

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

Kaya, gamit ang id_token, maaari mong ilipat ang lahat ng kinakailangang mga palatandaan sa payload ng token at huwag makipag-ugnayan sa server ng pahintulot sa bawat oras upang humiling ng data ng user. Ang kawalan ng diskarteng ito ay ang pagbabago sa data ng user mula sa server ay hindi kaagad dumarating, ngunit kasama ng isang bagong access token.

Mga resulta ng pagpapatupad

Kaya, pagkatapos ipatupad ang aming sariling OIDC server at i-configure ang mga koneksyon dito sa panig ng aplikasyon, nalutas namin ang problema sa paglilipat ng impormasyon tungkol sa mga user.
Dahil ang OIDC ay isang bukas na pamantayan, mayroon kaming opsyon na pumili ng umiiral na provider o pagpapatupad ng server. Sinubukan namin ang Keycloak, na naging napaka-maginhawang i-configure, pagkatapos mag-set up at baguhin ang mga configuration ng koneksyon sa gilid ng application, handa na itong umalis. Sa panig ng application, ang natitira na lang ay baguhin ang mga configuration ng koneksyon.

Pinag-uusapan ang mga umiiral na solusyon

Sa loob ng aming organisasyon, bilang unang server ng OIDC, binuo namin ang aming sariling pagpapatupad, na dinagdagan kung kinakailangan. Pagkatapos ng isang detalyadong pagsusuri ng iba pang mga handa na solusyon, maaari naming sabihin na ito ay isang pinagtatalunang punto. Sa pabor sa desisyon na ipatupad ang kanilang sariling server, may mga alalahanin sa bahagi ng mga provider sa kawalan ng kinakailangang pag-andar, pati na rin ang pagkakaroon ng isang lumang sistema kung saan mayroong iba't ibang mga custom na awtorisasyon para sa ilang mga serbisyo at medyo marami. ng data tungkol sa mga empleyado ay naimbak na. Gayunpaman, sa mga handa na pagpapatupad, may mga kaginhawahan para sa pagsasama. Halimbawa, ang Keycloak ay may sariling sistema ng pamamahala ng gumagamit at ang data ay direktang naka-imbak sa loob nito, at hindi magiging mahirap na maabutan ang iyong mga user doon. Para magawa ito, may API ang Keycloak na magbibigay-daan sa iyong ganap na isagawa ang lahat ng kinakailangang pagkilos sa paglilipat.

Ang isa pang halimbawa ng isang sertipikado, kawili-wili, sa aking opinyon, ang pagpapatupad ay Ory Hydra. Ito ay kawili-wili dahil ito ay binubuo ng iba't ibang bahagi. Upang maisama, kakailanganin mong i-link ang iyong serbisyo sa pamamahala ng user sa kanilang serbisyo ng awtorisasyon at palawigin kung kinakailangan.

Ang Keycloak at Ory Hydra ay hindi lamang ang mga off-the-shelf na solusyon. Pinakamainam na pumili ng isang pagpapatupad na na-certify ng OpenID Foundation. Karaniwang mayroong OpenID Certification badge ang mga solusyong ito.

OpenID Connect: awtorisasyon ng mga panloob na application mula sa custom hanggang sa karaniwan

Huwag ding kalimutan ang tungkol sa mga umiiral nang bayad na provider kung ayaw mong panatilihin ang iyong OIDC server. Ngayon maraming magagandang pagpipilian.

kung ano ang susunod

Sa malapit na hinaharap, isasara namin ang trapiko sa mga panloob na serbisyo sa ibang paraan. Plano naming ilipat ang aming kasalukuyang SSO sa balancer gamit ang OpenResty sa isang proxy batay sa OAuth. Mayroon nang maraming handa na solusyon dito, halimbawa:
github.com/bitly/oauth2_proxy
github.com/ory/oathkeeper
github.com/keycloak/keycloak-gatekeeper

Karagdagang mga materyales

jwt.io – magandang serbisyo para sa pagpapatunay ng mga token ng JWT
openid.net/developers/certified - listahan ng mga sertipikadong pagpapatupad ng OIDC

Pinagmulan: www.habr.com

Magdagdag ng komento