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 това се нарича Claims. Искове са по същество крайни полета в потребителската база данни (име, имейл, телефон и т.н.). Съществува стандартен списък с печати, а всичко, което не е включено в този списък, се счита за персонализирано. Следователно, първата точка, на която трябва да обърнете внимание, ако искате да изберете съществуващ доставчик на OIDC, е възможността за удобно персонализиране на нови марки.

Групата от отличителни знаци е комбинирана в следното подмножество - Обхват. При оторизацията се иска достъп не до конкретни марки, а до обхвати, дори ако някои от марките от обхвата не са необходими.

2) Внедри необходимите безвъзмездни средства

Следващата част от OIDC интеграцията е изборът и внедряването на типове авторизация, така наречените грантове. По-нататъшният сценарий на взаимодействие между избраното приложение и сървъра за оторизация ще зависи от избраното разрешение. Примерна схема за избор на правилната субсидия е показана на фигурата по-долу.

OpenID Connect: оторизация на вътрешни приложения от персонализирани до стандартни

За първото ни приложение използвахме най-често срещаното разрешение, кода за оторизация. Разликата му от другите е, че е тристепенен, т.е. се подлага на допълнителни изследвания. Първо, потребителят прави заявка за разрешение за оторизация, получава токен - Код за оторизация, след което с този токен, като при билет за пътуване, иска токен за достъп. Цялото основно взаимодействие на този скрипт за оторизация се основава на пренасочвания между приложението и сървъра за оторизация. Можете да прочетете повече за тази субсидия тук.

OAuth се придържа към концепцията, че токените за достъп, получени след оторизация, трябва да бъдат временни и трябва да се променят, за предпочитане средно на всеки 10 минути. Предоставянето на код за оторизация е проверка в три стъпки чрез пренасочвания, на всеки 10 минути, за да обърнете такава стъпка, честно казано, не е най-приятната задача за очите. За решаването на този проблем има друг грант - Refresh Token, който използвахме и у нас. Тук всичко е по-лесно. По време на проверка от друг грант, в допълнение към основния токен за достъп, се издава още един - Refresh Token, който може да се използва само веднъж и животът му обикновено е много по-дълъг. С този токен за опресняване, когато TTL (Time to Live) на основния токен за достъп приключи, заявката за нов токен за достъп ще стигне до крайната точка на друго разрешение. Използваният 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 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

Добавяне на нов коментар