OpenID Connect: rajtigo de internaj aplikoj de kutimo ĝis normo

Antaŭ kelkaj monatoj mi efektivigis OpenID Connect-servilon por administri aliron por centoj da niaj internaj aplikaĵoj. De niaj propraj evoluoj, oportunaj en pli malgranda skalo, ni transiris al ĝenerale akceptita normo. Aliro per centra servo signife simpligas monotonajn operaciojn, reduktas la koston de efektivigo de rajtigoj, ebligas trovi multajn pretajn solvojn kaj ne skui viajn cerbojn dum disvolvado de novaj. En ĉi tiu artikolo mi parolos pri ĉi tiu transiro kaj la ŝvelaĵoj, kiujn ni sukcesis trafi.

OpenID Connect: rajtigo de internaj aplikoj de kutimo ĝis normo

Antaŭ longe... Kie ĉio komenciĝis

Antaŭ pluraj jaroj, kiam internaj aplikoj fariĝis tro multaj por mane administri, ni skribis aplikaĵon por kontroli aliron ene de la kompanio. Ĝi estis simpla Rails-aplikaĵo, kiu konektiĝis al datumbazo kun informoj pri dungitoj, kie aliro al diversaj funkcioj estis agordita. Samtempe, ni lanĉis la unuan SSO, kiu baziĝis sur konfirmo de ĵetonoj fare de la kliento kaj la rajtiga servilo; la ĵetono estis transdonita en ĉifrita formo kun pluraj parametroj kaj kontrolita sur la rajtiga servilo. Ĉi tio ne estis la plej oportuna opcio, ĉar ĉiu interna aplikaĵo devis priskribi konsiderindan tavolon de logiko, kaj dungitaj datumbazoj estis tute sinkronigitaj kun la rajtiga servilo.

Post iom da tempo, ni decidis simpligi la taskon de centralizita rajtigo. SSO estis transdonita al la ekvilibristo. Kun la helpo de OpenResty, ŝablono estis aldonita al Lua kiu kontrolis ĵetonojn, sciis al kiu aplikaĵo la peto iras, kaj povis kontroli ĉu ekzistas aliro tie. Ĉi tiu aliro multe simpligis la taskon kontroli aliron al internaj aplikaĵoj - ne plu necesis priskribi plian logikon en la kodo de ĉiu aplikaĵo. Kiel rezulto, ni fermis la trafikon ekstere, sed la aplikaĵo mem sciis nenion pri rajtigo.

Tamen unu problemo restis nesolvita. Kio pri aplikaĵoj, kiuj bezonas informojn pri dungito? Eblis skribi API por la rajtiga servo, sed tiam vi devus aldoni plian logikon por ĉiu tia aplikaĵo. Krome, ni volis forigi la dependecon de unu el niaj memskribitaj aplikaĵoj, kiu estas plu fokusita al tradukado en OpenSource, sur nia interna rajtiga servilo. Pri tio ni rakontos al vi alian fojon. La solvo al ambaŭ problemoj estis OAuth.

Al ĝenerale akceptitaj normoj

OAuth estas klara, ĝenerale akceptita rajtigonormo, sed ĉar ĝia funkcieco sole ne sufiĉas, OpenID Connect (OIDC) tuj estis pripensita. OIDC mem estas la tria efektivigo de la malferma konfirmnormo, kiu evoluis al superaro de la OAuth 2.0 protokolo (Open Authorization Protocol). Ĉi tiu solvo solvas la problemon de manko de datumoj pri la fina uzanto, kaj ankaŭ ebligas ŝanĝi la rajtigan provizanton.

Tamen, ni ne elektis specifan provizanton kaj decidis aldoni integriĝon kun OIDC por nia ekzistanta rajtiga servilo. Ĉi tiu decido estis subtenata de la fakto, ke OIDC estas tre fleksebla laŭ rajtigo de finuzanto. Tiel, eblis efektivigi OIDC-subtenon sur via nuna rajtiga servilo.

OpenID Connect: rajtigo de internaj aplikoj de kutimo ĝis normo

Nia vojo al efektivigo de nia propra OIDC-servilo

1) Alportu la datumojn en la bezonatan formon

Por integri OIDC, estas necese alporti aktualajn uzantdatenojn en formo kiu estas komprenebla al la normo. En OIDC tio estas nomita Asertoj. Markoj estas esence la finaj kampoj en la uzantdatumbazo (nomo, retpoŝto, telefono, ktp.). Ekzistas norma listo de markoj, kaj ĉio, kio ne estas inkluzivita en ĉi tiu listo, estas konsiderata kutimo. Tial, la unua punkto, al kiu vi devas atenti, se vi volas elekti ekzistantan OIDC-provizanton, estas la kapablo oportune personecigi novajn poŝtmarkojn.

La grupo de markoj estas kombinita en la sekvan subaron - Amplekso. Dum rajtigo, aliro estas petita ne al specifaj markoj, sed al amplekso, eĉ se kelkaj el la markoj de la amplekso ne estas bezonataj.

2) Realigis la necesajn subvenciojn

La sekva parto de OIDC-integriĝo estas la elekto kaj efektivigo de rajtigaj tipoj, nomataj subvencioj. La plia scenaro de interago inter la elektita aplikaĵo kaj la rajtiga servilo dependos de la elektita subvencio. Proksimuma skemo por elekti la ĝustan subvencion estas prezentita en la suba figuro.

OpenID Connect: rajtigo de internaj aplikoj de kutimo ĝis normo

Por nia unua kandidatiĝo, ni uzis la plej oftan subvencion - Rajtigan Kodon. Ĝia diferenco de aliaj estas ke ĝi estas triŝtupa, t.e. suferas pliajn provojn. Unue, la uzanto faras peton pri permeso de rajtigo, ricevas ĵetonon de Rajtigo-Kodo, poste per ĉi tiu ĵetono, kvazaŭ kun vojaĝbileto, petas alir-ĵetonon. La tuta ĉefa interago de ĉi tiu rajtiga scenaro baziĝas sur alidirektiloj inter la aplikaĵo kaj la rajtiga servilo. Vi povas legi pli pri ĉi tiu subvencio tie.

OAuth aliĝas al la koncepto, ke la alirĵetonoj ricevitaj post rajtigo estu provizoraj kaj prefere ŝanĝiĝu averaĝe ĉiujn 10 minutojn. La subvencio pri Rajtkodo estas tri-ŝtupa konfirmo per alidirektiloj; plenumi tian paŝon ĉiujn 10 minutojn, sincere, ne estas la plej agrabla tasko por la okulo. Por solvi ĉi tiun problemon, ekzistas alia subvencio - Refresh Token, kiun ni ankaŭ uzis. Ĉio estas pli simpla ĉi tie. Dum konfirmo de alia subvencio, krom la ĉefa alirĵetono, alia estas eldonita - Refresh Token, kiu povas esti uzata nur unufoje kaj ĝia vivdaŭro, kiel regulo, estas signife pli longa. Kun ĉi tiu Refresh Token, kiam la TTL (Tempo por Vivi) de la ĉefa alirĵetono finiĝas, peto por nova alirĵetono venos al la finpunkto de alia subvencio. La uzita Refresh Token tuj rekomenciĝas al nulo. Ĉi tiu kontrolo estas dupaŝa kaj povas esti farita en la fono, nerimarkite de la uzanto.

3) Agordis uzantajn datumajn eligajn formatojn

Post kiam la elektitaj subvencioj estas efektivigitaj, la rajtigo funkcias, indas mencii la ricevon de datumoj de finuzantoj. OIDC havas apartan finpunkton por ĉi tio, kie vi povas peti uzantajn datumojn kun via nuna alirĵetono kaj se ĝi estas ĝisdatigita. Kaj se la uzantdatenoj ne tiom ofte ŝanĝiĝas, sed vi devas multfoje iri por la nunaj, vi povas veni al solvo kiel JWT-ĵetonoj. Ĉi tiuj ĵetonoj ankaŭ estas subtenataj de la normo. La JWT-ĵetono mem konsistas el tri partoj: kaplinio (informoj pri la ĵetono), utila ŝarĝo (ajna necesaj datumoj) kaj subskribo (subskribo, la ĵetono estas subskribita de la servilo kaj estonte vi povas kontroli la fonton de ĝia subskribo).

En la OIDC-efektivigo, la JWT-ĵetono estas nomita id_token. Ĝi povas esti petita kune kun regula alirĵetono kaj restas nur kontroli la subskribon. Tiucele, la rajtiga servilo havas apartan finpunkton kun amaso da publikaj ŝlosiloj en la formato J.W.K.. Kaj parolante pri tio, indas mencii, ke ekzistas alia finpunkto, kiu baziĝas sur la normo RFC5785 reflektas la nunan agordon de la OIDC-servilo. Ĝi enhavas ĉiujn finpunkto-adresojn (inkluzive de la adreso de la publika ŝlosilringo uzita por subskribado), apogitajn poŝtmarkojn kaj ampleksojn, uzitajn ĉifradalgoritmojn, subtenatajn subvenciojn, ktp.

Ekzemple en Guglo:

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

Tiel, uzante id_token vi povas transdoni ĉiujn necesajn markojn al la ĵeton-utila ŝarĝo kaj ne kontakti la rajtigan servilon ĉiufoje por peti uzantajn datumojn. La malavantaĝo de ĉi tiu aliro estas, ke ŝanĝoj en uzantdatenoj de la servilo ne venas tuj, sed kune kun nova alirĵetono.

Rezultoj de efektivigo

Do, post efektivigi nian propran OIDC-servilon kaj agordi konektojn al ĝi ĉe la aplikaĵo, ni solvis la problemon de transdoni uzantajn informojn.
Ĉar OIDC estas malferma normo, ni nun havas la eblon elekti ekzistantan provizanton aŭ servilan efektivigon. Ni provis Keycloak, kiu montriĝis tre facila por agordi; post agordo kaj ŝanĝo de konekto-agordoj ĉe la aplikaĵo, ĝi estas preta. Sur la aplikaĵo, restas nur ŝanĝi la konektajn agordojn.

Parolante pri ekzistantaj solvoj

Ene de nia organizo, kiel la unua OIDC-servilo, ni kolektis nian propran efektivigon, kiu estis kompletigita laŭbezone. Post detala ekzameno de aliaj pretaj solvoj, ni povas diri, ke tio estas polemika punkto. La decido efektivigi nian propran servilon estis pelita de zorgoj de provizantoj pri la manko de necesa funkcieco, same kiel la ĉeesto de malnova sistemo, kiu enhavis diversajn kutimajn rajtigojn por iuj servoj kaj jam konservis sufiĉe da datumoj pri dungitoj. . Tamen, en pretaj efektivigoj, ekzistas oportunoj por integriĝo. Ekzemple, Keycloak havas sian propran uzantan administradsistemon kaj datumoj estas stokitaj rekte en ĝi, kaj movi viajn uzantojn tien ne estos malfacila. Por ĉi tiu celo, Keycloak havas API, kiu permesos al vi plene plenumi ĉiujn necesajn translokajn agojn.

Alia ekzemplo de atestita, interesa, laŭ mi, efektivigo estas Ory Hydra. Ĝi estas interesa ĉar ĝi konsistas el malsamaj komponantoj. Por integri, vi devos ligi vian uzantan administradon al ilia rajtiga servo kaj pligrandigi laŭbezone.

Keycloak kaj Ory Hydra ne estas la nuraj pretaj solvoj. Plej bone estas elekti efektivigon atestitan de la OpenID Foundation. Ĉi tiuj solvoj kutime havas OpenID Certification-insignon.

OpenID Connect: rajtigo de internaj aplikoj de kutimo ĝis normo

Ankaŭ ne forgesu pri ekzistantaj pagitaj provizantoj se vi ne volas konservi vian OIDC-servilon. Hodiaŭ estas multaj bonaj opcioj.

Kio sekvas

En proksima estonteco, ni fermos trafikon al internaj servoj alimaniere. Ni planas migri nian nunan SSO al la ekvilibristo uzante OpenResty al prokurilo bazita sur OAuth. Estas ankaŭ multaj pretaj solvoj ĉi tie, ekzemple:
github.com/bitly/oauth2_proxy
github.com/ory/oathkeeper
github.com/keycloak/keycloak-gatekeeper

Pliaj materialoj

jwt.io - bona servo por kontroli JWT-ĵetonojn
openid.net/developers/certified - listo de atestitaj OIDC-efektivigoj

fonto: www.habr.com

Aldoni komenton