OpenID Connect: овластување на внатрешни апликации од прилагодено до стандардно

Пред неколку месеци, имплементирав OpenID Connect сервер за управување со пристапот за стотици наши внатрешни апликации. Од нашите сопствени случувања, погодни во помал обем, се преселивме на општо прифатен стандард. Пристапот преку централната услуга во голема мера ги поедноставува монотоните операции, ги намалува трошоците за спроведување на овластувањата, ви овозможува да најдете многу готови решенија и да не ги оптеретувате вашите мозоци кога развивате нови. Во оваа статија ќе зборувам за оваа транзиција и за нерамнините што успеавме да ги пополниме.

OpenID Connect: овластување на внатрешни апликации од прилагодено до стандардно

Одамна... Како почна се

Пред неколку години, кога имаше премногу интерни апликации за рачна контрола, напишавме апликација за контрола на пристапот во компанијата. Тоа беше едноставна апликација Rails која се поврзуваше со база на податоци со информации за вработените, каде што беше конфигуриран пристапот до различни функционалности. Во исто време, го подигнавме првиот ДЗС, кој се базираше на верификација на токените од страната на клиентот и серверот за овластување, токенот беше пренесен во шифрирана форма со неколку параметри и верифициран на серверот за авторизација. Ова не беше најзгодната опција, бидејќи секоја внатрешна апликација мораше да опише значителен слој на логика, а базите на податоци на вработените беа целосно синхронизирани со серверот за овластување.

По некое време, решивме да ја поедноставиме задачата за централизирано овластување. ДЗС беше префрлен на балансерот. Со помош на 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, кој го користевме и кај нас. Сè е полесно овде. При верификација од друг грант, покрај главниот токен за пристап, се издава уште еден - Refresh Token, кој може да се користи само еднаш и неговиот животен век обично е многу подолг. Со овој токен за освежување, кога ќе заврши TTL (Време за живот) на главниот токен за пристап, барањето за нов токен за пристап ќе дојде до крајната точка на друг грант. Искористениот токен за освежување веднаш се ресетира на нула. Оваа проверка е во два чекора и може да се изврши во позадина, незабележливо за корисникот.

3) Поставете сопствени формати за излез на податоци

Откако ќе се имплементираат избраните грантови, ќе функционира авторизацијата, вреди да се спомене добивање податоци за крајниот корисник. OIDC има посебна крајна точка за ова, каде што можете да барате кориснички податоци со вашиот тековен токен за пристап и ако е ажуриран. И ако податоците на корисникот не се менуваат толку често, а треба да ги следите тековните многу пати, можете да дојдете до такво решение како JWT токени. Овие токени се исто така поддржани од стандардот. Самиот токен JWT се состои од три дела: заглавие (информации за токенот), носивост (било какви потребни податоци) и потпис (потпис, токенот е потпишан од серверот и подоцна можете да го проверите изворот на неговиот потпис).

Во имплементацијата на OIDC, токенот JWT се нарекува id_token. Може да се побара заедно со нормален токен за пристап и се што останува е да се потврди потписот. Серверот за овластување има посебна крајна точка за ова со еден куп јавни клучеви во формат ЏВК. А зборувајќи за ова, вреди да се спомене дека постои уште една крајна точка, која, врз основа на стандардот 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 што ќе ви овозможи целосно да ги извршите сите потребни акции за пренос.

Друг пример за сертифицирана, интересна, според мое мислење, имплементација е Ори Хидра. Интересно е затоа што се состои од различни компоненти. За да се интегрирате, ќе треба да ја поврзете вашата услуга за управување со корисници со нивната услуга за овластување и да ја проширите по потреба.

Keycloak и Ory Hydra не се единствените решенија кои не се достапни на полица. Најдобро е да изберете имплементација потврдена од Фондацијата OpenID. Овие решенија обично имаат значка за сертификација OpenID.

OpenID Connect: овластување на внатрешни апликации од прилагодено до стандардно

Исто така, не заборавајте за постоечките платени провајдери ако не сакате да го задржите вашиот OIDC сервер. Денес има многу добри опции.

Што е следно

Во блиска иднина, ќе го затвориме сообраќајот кон внатрешните услуги на поинаков начин. Планираме да ја пренесеме нашата сегашна ДЗС на балансерот користејќи 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

Додадете коментар