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 провайдерін таңдағыңыз келсе, назар аударуыңыз керек бірінші мәселе - жаңа брендтерді ыңғайлы теңшеу мүмкіндігі.

Белгілер тобы келесі ішкі жиынға біріктірілген - Ауқым. Рұқсат ету кезінде белгілі бір брендтерге емес, ауқымдарға рұқсат сұралады, тіпті кейбір ауқымдағы брендтер қажет болмаса да.

2) Қажетті гранттарды жүзеге асырды

OIDC интеграциясының келесі бөлігі – гранттар деп аталатын рұқсат түрлерін таңдау және енгізу. Таңдалған қолданба мен авторизация сервері арасындағы өзара әрекеттесу сценарийі таңдалған грантқа байланысты болады. Дұрыс грантты таңдаудың үлгілік схемасы төмендегі суретте көрсетілген.

OpenID Connect: ішкі қолданбаларды пайдаланушыдан стандартқа дейін авторизациялау

Бірінші өтініміміз үшін біз ең көп таралған грантты, Авторизация кодын пайдаландық. Оның басқалардан ерекшелігі – үш сатылы, т.б. қосымша сынақтан өтуде. Біріншіден, пайдаланушы авторизацияға рұқсат сұрауын жасайды, таңбалауыш – Авторизация кодын алады, содан кейін осы таңбалауышпен саяхатқа билет сияқты рұқсат белгісін сұрайды. Бұл авторизация сценарийінің барлық негізгі өзара әрекеттесуі қолданба мен авторизация сервері арасындағы қайта бағыттауларға негізделген. Сіз бұл грант туралы толығырақ оқи аласыз осында.

OAuth авторизациядан кейін алынған қол жеткізу токендері уақытша болуы керек және орташа есеппен әр 10 минут сайын жақсырақ өзгеруі керек деген тұжырымдаманы ұстанады. Авторизациялық код гранты - бұл қайта бағыттау арқылы үш сатылы тексеру, әрбір 10 минут сайын мұндай қадамды бұру, шынын айтқанда, көзге ең жағымды тапсырма емес. Бұл мәселені шешу үшін тағы бір грант – Refresh Token бар, оны өз елімізде де қолдандық. Мұнда бәрі оңайырақ. Басқа гранттан растау кезінде негізгі қол жеткізу таңбалауышынан басқа тағы біреуі шығарылады - Жаңарту Токені, оны тек бір рет пайдалануға болады және оның қызмет ету мерзімі әдетте әлдеқайда ұзағырақ. Осы Жаңарту таңбалауышымен негізгі қатынас токенінің TTL (Тірілу уақыты) аяқталғанда, жаңа рұқсат белгісіне сұрау басқа гранттың соңғы нүктесіне келеді. Пайдаланылған Жаңарту таңбалауышы бірден нөлге қайтарылады. Бұл тексеру екі қадамды және пайдаланушыға байқалмайтын фондық режимде орындалуы мүмкін.

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 Foundation сертификатталған енгізуді таңдаған дұрыс. Бұл шешімдерде әдетте 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 сертификатталған енгізулерінің тізімі

Ақпарат көзі: www.habr.com

пікір қалдыру