OpenID Connect. ներքին հավելվածների թույլտվություն մաքսայինից մինչև ստանդարտ

Մի քանի ամիս առաջ ես ներդնում էի OpenID Connect սերվեր՝ մեր հարյուրավոր ներքին հավելվածների հասանելիությունը կառավարելու համար: Մեր սեփական զարգացումներից, ավելի փոքր մասշտաբով հարմար, մենք անցել ենք ընդհանուր ընդունված ստանդարտի: Կենտրոնական ծառայության միջոցով մուտքը մեծապես հեշտացնում է միապաղաղ գործառնությունները, նվազեցնում թույլտվությունների իրականացման ծախսերը, թույլ է տալիս գտնել բազմաթիվ պատրաստի լուծումներ և չխորացնել ձեր ուղեղը նորերը մշակելիս: Այս հոդվածում ես կխոսեմ այս անցման և այն բախումների մասին, որոնք մենք կարողացանք լրացնել:

OpenID Connect. ներքին հավելվածների թույլտվություն մաքսայինից մինչև ստանդարտ

Վաղուց... Ինչպես ամեն ինչ սկսվեց

Մի քանի տարի առաջ, երբ ձեռքով հսկողության համար չափազանց շատ ներքին հավելվածներ կային, մենք դիմում գրեցինք ընկերության ներսում հասանելիությունը վերահսկելու համար: Դա Rails-ի պարզ հավելված էր, որը միանում էր աշխատակիցների մասին տեղեկություններով տվյալների բազայի, որտեղ կարգավորվում էր տարբեր գործառույթների հասանելիությունը: Միևնույն ժամանակ, մենք բարձրացրինք առաջին SSO-ն, որը հիմնված էր հաճախորդի և լիազորման սերվերի կողմից թոքենների ստուգման վրա, նշանը գաղտնագրված ձևով փոխանցվեց մի քանի պարամետրերով և ստուգվեց լիազորման սերվերի վրա: Սա ամենահարմար տարբերակը չէր, քանի որ յուրաքանչյուր ներքին հավելված պետք է նկարագրեր տրամաբանության զգալի շերտ, և աշխատակիցների տվյալների բազաները լիովին համաժամանակացվեցին լիազորման սերվերի հետ:

Որոշ ժամանակ անց մենք որոշեցինք պարզեցնել կենտրոնացված թույլտվության խնդիրը: SSO-ն փոխանցվել է հավասարակշռողին: OpenResty-ի օգնությամբ Lua-ին ավելացվեց կաղապար, որը ստուգում էր ժետոնները, գիտեր, թե որ հավելվածն է գնում հարցումը և կարող էր ստուգել, ​​թե արդյոք այնտեղ մուտք կա: Այս մոտեցումը զգալիորեն պարզեցրեց ներքին հավելվածների հասանելիությունը վերահսկելու խնդիրը. յուրաքանչյուր հավելվածի կոդում այլևս անհրաժեշտ չէր նկարագրել լրացուցիչ տրամաբանություն: Արդյունքում մենք փակեցինք երթևեկությունը արտաքինից, և հավելվածն ինքնին ոչինչ չգիտեր թույլտվության մասին։

Սակայն մի խնդիր չլուծված մնաց. Իսկ ի՞նչ կասեք այն հավելվածների մասին, որոնք աշխատակիցների մասին տեղեկությունների կարիք ունեն: Հնարավոր էր API գրել լիազորման ծառայության համար, բայց հետո դուք պետք է հավելյալ տրամաբանություն ավելացնեիք յուրաքանչյուր նման հավելվածի համար։ Բացի այդ, մենք ցանկանում էինք ձերբազատվել կախվածությունից մեր սեփական գրավոր հավելվածներից մեկից, որն ապագայում ուղղված է OpenSource-ի թարգմանության համար՝ մեր ներքին լիազորման սերվերից: Մենք դրա մասին կխոսենք մեկ այլ ժամանակ: Երկու խնդիրների լուծումն էլ OAuth-ն էր:

ընդհանուր չափանիշներին

OAuth-ը հասկանալի, ընդհանուր առմամբ ընդունված թույլտվության ստանդարտ է, բայց քանի որ միայն դրա ֆունկցիոնալությունը բավարար չէ, նրանք անմիջապես սկսեցին դիտարկել OpenID Connect-ը (OIDC): OIDC-ն ինքնին բաց վավերացման ստանդարտի երրորդ ներդրումն է, որը հոսել է հավելման մեջ OAuth 2.0 արձանագրության վրա (բաց թույլտվության արձանագրություն): Այս լուծումը փակում է վերջնական օգտագործողի մասին տվյալների բացակայության խնդիրը, ինչպես նաև հնարավորություն է տալիս փոխել թույլտվության մատակարարին:

Այնուամենայնիվ, մենք չընտրեցինք կոնկրետ մատակարար և որոշեցինք ավելացնել ինտեգրում OIDC-ի հետ մեր առկա թույլտվության սերվերի համար: Այս որոշման օգտին էր այն փաստը, որ OIDC-ն շատ ճկուն է վերջնական օգտագործողի թույլտվության առումով: Այսպիսով, հնարավոր եղավ իրականացնել OIDC աջակցություն ձեր ընթացիկ թույլտվության սերվերի վրա:

OpenID Connect. ներքին հավելվածների թույլտվություն մաքսայինից մինչև ստանդարտ

Մեր սեփական OIDC սերվերի ներդրման մեր եղանակը

1) Տվյալները բերեց ցանկալի ձևին

OIDC-ն ինտեգրելու համար անհրաժեշտ է ընթացիկ օգտագործողի տվյալները բերել ստանդարտով հասկանալի ձևի: OIDC-ում դա կոչվում է Հայցեր: Հայցերն ըստ էության օգտատերերի տվյալների բազայի վերջնական դաշտերն են (անուն, էլ.փոստ, հեռախոս և այլն): Գոյություն ունի նամականիշերի ստանդարտ ցուցակ, և այն ամենը, ինչ ներառված չէ այս ցանկում, համարվում է սովորական։ Հետևաբար, առաջին կետը, որին դուք պետք է ուշադրություն դարձնեք, եթե ցանկանում եք ընտրել գոյություն ունեցող OIDC մատակարար, նոր ապրանքանիշերի հարմարեցման հնարավորությունն է:

Հատկանշական նշանների խումբը համակցված է հետևյալ ենթաբազմության մեջ՝ Scope: Թույլտվության ընթացքում պահանջվում է մուտք գործել ոչ թե կոնկրետ ապրանքանիշերի, այլ շրջանակների, նույնիսկ եթե շրջանակից որոշ ապրանքանիշեր անհրաժեշտ չեն:

2) իրականացրել է անհրաժեշտ դրամաշնորհներ

OIDC-ի ինտեգրման հաջորդ մասը թույլտվության տեսակների, այսպես կոչված, դրամաշնորհների ընտրությունն ու իրականացումն է: Ընտրված հավելվածի և թույլտվության սերվերի միջև փոխգործակցության հետագա սցենարը կախված կլինի ընտրված դրամաշնորհից: Ճիշտ դրամաշնորհ ընտրելու օրինակելի սխեման ներկայացված է ստորև նկարում:

OpenID Connect. ներքին հավելվածների թույլտվություն մաքսայինից մինչև ստանդարտ

Մեր առաջին դիմումի համար մենք օգտագործեցինք ամենատարածված դրամաշնորհը՝ Լիազորման օրենսգիրքը: Նրա տարբերությունը մյուսներից այն է, որ այն եռաստիճան է, այսինքն. լրացուցիչ թեստավորում է անցնում։ Սկզբում օգտատերը կատարում է թույլտվության թույլտվության հարցում, ստանում է նշան՝ Թույլտվության կոդը, այնուհետև այս նշանով, կարծես ճանապարհորդության տոմսով, խնդրում է մուտքի նշան: Այս թույլտվության սցենարի բոլոր հիմնական փոխազդեցությունը հիմնված է հավելվածի և թույլտվության սերվերի միջև վերահղումների վրա: Դուք կարող եք կարդալ ավելին այս դրամաշնորհի մասին այստեղ.

OAuth-ը հավատարիմ է այն հայեցակարգին, որ թույլտվությունից հետո ձեռք բերված մուտքի նշանները պետք է լինեն ժամանակավոր և գերադասելիորեն փոխվեն միջինը 10 րոպեն մեկ: Թույլտվության օրենսգրքի դրամաշնորհը եռաստիճան ստուգում է վերահղումների միջոցով, յուրաքանչյուր 10 րոպեն մեկ նման քայլ անելը, անկեղծ ասած, ամենահաճելի գործը չէ աչքերի համար: Այս խնդիրը լուծելու համար կա ևս մեկ դրամաշնորհ՝ Refresh Token-ը, որն օգտագործել ենք նաև մեր երկրում։ Այստեղ ամեն ինչ ավելի հեշտ է։ Մեկ այլ դրամաշնորհից ստուգման ժամանակ, բացի հիմնական մուտքի նշանից, տրվում է ևս մեկը՝ Refresh Token-ը, որը կարող է օգտագործվել միայն մեկ անգամ, և դրա ժամկետը սովորաբար շատ ավելի երկար է: Այս Refresh Token-ի միջոցով, երբ հիմնական մուտքի նշանի TTL-ը (Ապրելու ժամանակը) ավարտվի, մուտքի նոր նշանի հարցումը կհասնի մեկ այլ դրամաշնորհի վերջնական կետին: Օգտագործված Refresh Token-ը անմիջապես զրոյացվում է: Այս ստուգումը երկքայլ է և կարող է իրականացվել հետին պլանում՝ օգտագործողի համար աննկատ:

3) Ստեղծեք անհատական ​​տվյալների ելքային ձևաչափեր

Ընտրված դրամաշնորհների ներդրումից, լիազորման աշխատանքներից հետո հարկ է նշել վերջնական օգտագործողի մասին տվյալներ ստանալը։ OIDC-ն դրա համար ունի առանձին վերջնակետ, որտեղ դուք կարող եք պահանջել օգտվողի տվյալներ ձեր ընթացիկ մուտքի նշանով և եթե դրանք արդիական են: Իսկ եթե օգտատիրոջ տվյալներն այդքան հաճախ չեն փոխվում, և դուք պետք է բազմիցս հետևեք ընթացիկներին, կարող եք գալ այնպիսի լուծման, ինչպիսին են JWT տոկենները։ Այս նշանները նույնպես աջակցվում են ստանդարտով: JWT նշանն ինքնին բաղկացած է երեք մասից՝ վերնագիր (տեղեկատվություն նշանի մասին), օգտակար բեռ (ցանկացած անհրաժեշտ տվյալ) և ստորագրություն (ստորագրություն, նշանը ստորագրված է սերվերի կողմից և հետագայում կարող եք ստուգել դրա ստորագրության աղբյուրը)։

OIDC-ի իրականացման ժամանակ JWT նշանը կոչվում է id_token: Այն կարող է պահանջվել սովորական մուտքի նշանի հետ միասին, և մնում է միայն ստուգել ստորագրությունը: Լիազորման սերվերը դրա համար ունի առանձին վերջնակետ՝ ձևաչափով մի շարք հանրային բանալիներով J.W.K.. Եվ այս մասին խոսելիս հարկ է նշել, որ կա ևս մեկ վերջնակետ, որը, ելնելով ստանդարտից RFC5785- ը արտացոլում է OIDC սերվերի ընթացիկ կոնֆիգուրացիան: Այն պարունակում է բոլոր վերջնակետի հասցեները (ներառյալ ստորագրման համար օգտագործվող հանրային բանալիների օղակի հասցեն), աջակցվող ապրանքանիշերն ու շրջանակները, օգտագործված գաղտնագրման ալգորիթմները, աջակցվող դրամաշնորհները և այլն:

Օրինակ 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"
 ]
}

Այսպիսով, օգտագործելով id_token, դուք կարող եք փոխանցել բոլոր անհրաժեշտ նշանները նշանի օգտակար բեռին և ամեն անգամ չկապվել թույլտվության սերվերի հետ՝ օգտատիրոջ տվյալները պահանջելու համար: Այս մոտեցման թերությունն այն է, որ սերվերից օգտվողի տվյալների փոփոխությունը անմիջապես չի կատարվում, այլ մուտքի նոր նշանի հետ միասին:

Իրականացման արդյունքները

Այսպիսով, մեր սեփական OIDC սերվերի ներդրումից և հավելվածի հետ կապերը կարգավորելուց հետո մենք լուծեցինք օգտվողների մասին տեղեկատվության փոխանցման խնդիրը:
Քանի որ OIDC-ն բաց ստանդարտ է, մենք հնարավորություն ունենք ընտրելու գոյություն ունեցող մատակարար կամ սերվերի ներդրում: Մենք փորձեցինք Keycloak-ը, որը պարզվեց, որ շատ հարմար է կարգավորելու համար, հավելվածի կողմից կապի կոնֆիգուրացիան կարգավորելուց և փոխելուց հետո այն պատրաստ է գործարկման: Դիմումի կողմում մնում է միայն փոխել կապի կոնֆիգուրացիաները:

Խոսելով առկա լուծումների մասին

Մեր կազմակերպության շրջանակներում, որպես առաջին OIDC սերվեր, մենք հավաքեցինք մեր սեփական ներդրումը, որը լրացվեց ըստ անհրաժեշտության: Այլ պատրաստի լուծումների մանրամասն վերանայումից հետո կարող ենք ասել, որ դա վիճելի հարց է: Սեփական սերվերի ներդրման որոշման օգտին, պրովայդերների կողմից մտահոգություններ կային անհրաժեշտ ֆունկցիոնալության բացակայության, ինչպես նաև հին համակարգի առկայության դեպքում, որում կային տարբեր մաքսային թույլտվություններ որոշ ծառայությունների համար և բավականին շատ: աշխատակիցների մասին տվյալներն արդեն պահպանվել են: Այնուամենայնիվ, պատրաստի իրագործումներում կան ինտեգրման հարմարություններ։ Օրինակ, Keycloak-ն ունի օգտատերերի կառավարման իր համակարգ, և տվյալները պահվում են անմիջապես դրա մեջ, և դժվար չի լինի այնտեղ առաջ անցնել ձեր օգտատերերից։ Դրա համար Keycloak-ն ունի API, որը թույլ կտա ամբողջությամբ իրականացնել փոխանցման բոլոր անհրաժեշտ գործողությունները:

Վկայագրված, հետաքրքիր, իմ կարծիքով, իրականացման մեկ այլ օրինակ Ory Hydra-ն է: Հետաքրքիր է, քանի որ այն բաղկացած է տարբեր բաղադրիչներից։ Ինտեգրվելու համար դուք պետք է կապեք ձեր օգտատերերի կառավարման ծառայությունը նրանց լիազորման ծառայությանը և անհրաժեշտության դեպքում ընդլայնեք:

Keycloak-ը և Ory Hydra-ն միակ լուծումները չեն, որոնք վաճառվում են: Ավելի լավ է ընտրել OpenID հիմնադրամի կողմից վավերացված իրականացում: Այս լուծումները սովորաբար ունեն OpenID հավաստագրման նշան:

OpenID Connect. ներքին հավելվածների թույլտվություն մաքսայինից մինչև ստանդարտ

Մի մոռացեք նաև առկա վճարովի մատակարարների մասին, եթե չեք ցանկանում պահպանել ձեր OIDC սերվերը: Այսօր շատ լավ տարբերակներ կան։

Ինչ է հաջորդը

Մոտ ապագայում մենք պատրաստվում ենք այլ կերպ փակել տրաֆիկը դեպի ներքին ծառայություններ։ Մենք նախատեսում ենք փոխանցել մեր ընթացիկ SSO-ն հաշվեկշռի վրա՝ օգտագործելով OpenResty-ը OAuth-ի վրա հիմնված վստահված անձի: Այստեղ արդեն շատ պատրաստի լուծումներ կան, օրինակ.
github.com/bitly/oauth2_proxy
github.com/ory/oathkeeper
github.com/keycloak/keycloak-gatekeeper

Լրացուցիչ նյութեր

jwt.io – լավ ծառայություն JWT նշանները վավերացնելու համար
openid.net/developers/certified - հավաստագրված OIDC իրականացումների ցանկը

Source: www.habr.com

Добавить комментарий