ru:https://highload.today/blogs/gotovogo-resheniya-net-kak-postroit-flou-avtorizatsii-moj-opyt-raboty-v-neskolkih-proektah/ ua:https://highload.today/uk/blogs/gotovogo-rishennya-nemaye-yak-pobuduvati-flou-avtorizatsiyi-mij-dosvid-roboti-u-kilkoh-proyektah/
logo
Досвід      07/10/2022

Готового рішення немає! Як побудувати флоу авторизації: мій досвід у кількох проєктах

Микола Коломієць BLOG

NET Developer у NIX

Про побудову флоу авторизації розробники замислюються мало не в кожному проєкті. Єдиного правильного рішення тут немає і бути не може.

Хороший авторизаційний флоу спирається на особливості бізнес-логіки та архітектури конкретного продукту, на цілі клієнта і технічні можливості команди розробки.

Саме про це я детальніше розповім у цій статті. Наведені поради базуються на моєму досвіді.

Про що поговоримо?

  • Розберемо два приклади побудови авторизаційного флоу. У першому випадку нашій команді потрібно було створити авторизацію за принципом Single Sign On із поділом пермісій користувачів між різними продуктами. Я покажу варіанти розв’язання задачі із кінцевим дизайном авторизації.
  • У другій частині поглянемо на legacy-проєкт, де треба покращити авторизаційний флоу на тлі міграції фіч до Azure. Я опишу, як ми позбавлялися вразливостей й адаптували авторизацію під новий функціонал. Причому з доробком під майбутню модернізацію продукту.
  • Як результат — ви дізнаєтесь, як у різних проєктах можна знаходити цікаві рішення залежно від ваших умов і специфіки задач.

Проєкт №1

Спершу коротко поясню суть проєкту. Він поєднує три продукти єдиного фармацевтичного сервісу. Один застосунок може відстежувати товари в аптеках, інший — моніторити стан пацієнтів. Користувачі сервісу мають вільно користуватися обома продуктами без повторної авторизації.

Налаштувати таку можливість і було нашим завданням. От тільки пермісії на кожному домені для кожного юзера різні. Десь користувач може створювати нові сторінки, десь — лише переглядати наявні. Це стало для нас головною складністю при реалізації авторизаційного флоу. Перш ніж пояснити, як ми втілювали тут принцип Single Sign On, коротко нагадаю, як він працює.

Single Sign On — це технологія, яка дозволяє авторизуватися один раз для використання декількох продуктів.

Онлайн-курс Frontend-разробник від Powercode academy.
Курс на якому ти напишеш свій чистий код на JavaScript, попрацюєш із різними видами верстки, а також адаптаціями проектів під будь-які екрани. .
Зарееструватися

До прикладу, є рішення Microsoft. Ви передаєте креди для входу в обліковий запис лише раз, а потім відкриваєте будь-які пов’язані ресурси: OneDrive, Office тощо. Це спрощує життя користувача та заощаджує його час.

Що потрібно для реалізації SSO? Беремо браузер-клієнт, два домени та єдиний авторизаційний сервер, де зберігаються користувачі обох доменів:

  • Коли неавторизований користувач намагається отримати доступ до першого домену, відбувається редирект на цей авторизаційний сервер. Там зазвичай перевіряються cookies клієнта.
  • Якщо вони чисті (тобто користувач ще не авторизувався на цьому сервері), йому необхідно ввести креди — логін та пароль.
  • Інформація про успішну авторизацію зберігається в cookies, система повертає користувача на перший домен — і юзер може ним користуватися.
  • Завдяки запису в cookies при повторному заході на цей домен користувач відразу потрапить до свого акаунту.

Далі він звертається до другого домену. Юзер там не авторизований, тому система перенаправляє його на той самий єдиний авторизаційний сервер. Він знову перевіряє cookies, бачить старий запис про успішну авторизацію та відкриває доступ і до другого домену. Знову ж таки без жодного введення кредів.

У нашому проєкті таких зв’язаних доменів було три, а в ролі авторизаційного серверу виступав KeyCloak. Користувачеві фармацевтичного сервісу достатньо один раз вказати логін та пароль, щоб отримати доступ до будь-якого з продуктів і легко переходити між ними:

Курс-професія "Копірайтер" від Skvot.
40 занять — і ти з упевненістю, скілами та портфоліо зможеш тиснути Apply на вакансії копірайтера.Досвідом і ключами поділяться 2 лекторки та запрошені спікери.
Детальніше про курс

Однак з авторизаційним флоу виникли складнощі відразу в декількох моментах:

  • Динамічні пермісії для користувачів. Права користувача на ті чи інші дії всередині продукту можуть призначатися «на льоту», комбінуватися і бути у складі різних груп. Тобто пермісія — це не просто роль, призначена юзеру. Користувач може переглядати сторінки пацієнтів, але не може їх оновлювати. Або ж оновлюватиме, але не створюватиме нових пацієнтів. У такому випадку SSO не підходить, адже з ним ролі статичні, а пермісії фіксовані.
  • Різні пермісії на різних продуктах. Для кожного з трьох доменів у межах проєкту набір і структура пермісій можуть відрізнятися. Це також ускладнює єдиний вхід за принципом Single Sign On.
  • Неможливість зміни авторизаційного сервера. Ми не могли доопрацювати KeyCloak під наші потреби. Адже до складу сервера входять не лише ці три продукти, а й інші. Модифікувати структуру неможна, хоча за необхідності достатньо розширити сервер.
  • Продуктивність. Перфоманс має бути високим, а тут це було під питанням. Швидкість обробки запитів, проходження авторизації та розподілу пермісій могли уповільнити процес, що взагалі неприйнятно.

З огляду на ці проблеми та наявні технічні можливості наша команда почала шукати рішення у межах SSO. Про кожен із шляхів розкажу окремо.

Авторизаційний флоу з реплікацією

Цей варіант здався очевидним. Що нас наштовхнуло на такий вибір, так це використання у проєкті реплікації — коли один продукт копіює дані з іншого. Тоді флоу виглядав би таким чином:

  • користувач проходить авторизацію на KeyCloak;
  • Онлайн курс UI/UX Design Pro від Ithillel.
    Навчіться проєктувати інтерфейси з урахуванням поведінки користувачів, розв'язувати їх проблеми через Customer Journey Mapping, створювати дизайн-системи і проводити дослідження юзабіліті, включаючи проєктування мобільних додатків для Android та iOS і розробку UX/UI на основі даних!
    Дізнатися більше
  • отримує Bearer Token;
  • і далі з ним переходить на будь-який із трьох продуктів.

На цьому етапі знадобиться Authorization Service — сховище пермісій. Усі три сервіси, з якими спілкується клієнт, використовуватимуть дані з Authorization Service та реплікуватимуть пермісії. Вони можуть зберігатися як у базі даних, так і в кеші.

У разі надходження запиту на читання, додавання або іншу дію користувача система звертатиметься до реплікованих пермісій та перевірятиме, чи є вони у цього користувача. Так процес відбувається в усіх продуктах:

Окрім вирішення питання пермісій, є й інші переваги флоу з реплікацією. Наприклад, вся інформація, що передається, буде актуальною. Це стає можливим за рахунок реплікування даних.

Та у цього підходу є недоліки:

  • Дублювання великих масивів даних. Кожен продукт копіює інформацію користувачів. Через це в системі виникає екстракол до БД або кешу для отримання пермісій конкретного юзера. Це серйозно вдарить по перфомансу сервісу.
  • Необхідність розробки механізму відображення пермісій в UI. Наприклад, якщо користувачеві заборонено створювати нових пацієнтів, то в меню потрібно блокувати кнопки, що відповідають за цю дію.
  • Курс Job Interview Crash Course від Enlgish4IT.
    Отримайте 6 шаблонів відповідей на співбесіді, які ви зможете використовувати для структурування своїх відповідей. Отримайте знижку 10% за промокодом ITCENG.
    Приєднатися

Тож ми знову почали розмірковувати над оптимальним рішенням…

Авторизаційний флоу з інформацією в Bearer-токені

Наступний варіант — розміщення інформації про права користувача у Bearer Token. При авторизації користувача KeyCloak може отримати пермісії зі сховища Authorization Service.

Сценарій вийшов би таким: користувач вводить логін і пароль, генерується Bearer-токен, і в нього записуються призначені авторизованому юзеру пермісії.

Коли клієнт надішле запит на той чи інший продукт, сервіс уже на своїй стороні сам валідує його:

Ось два відчутних плюси:

  • Немає дуплікації. Нам не треба копіювати складну логіку та великі масиви даних у кожному продукті
  • Спрощений клієнт. Застосунок буде полегшеним, без додаткової логіки. Він виконує лише авторизацію, а все потрібне є в токені. Клієнт витягує ці дані та застосовує їх у UI.

Однак і в цьому варіанті була пара серйозних недоліків:

Онлайн-курс "Excel та Power BI для аналізу даних" від robot_dreams.
Навчіться самостійно аналізувати й візуалізувати дані, знаходити зв’язки, розуміти кожен аспект отриманої інформації та перетворювати її на ефективні рішення.
Детальніше про курс
  • Розмір токена. При великій кількості пермісій Bearer-токен може перевищити допустиме значення хедерів у запиті. Це потенційно серйозна проблема. При цьому реальної потреби у перенесенні пермісій немає. Користувач може переходити з токеном на інші продукти. Як показали наші експерименти, при додаванні пермісій ми не досягли навіть половини допустимого розміру хедера. Далася взнаки обмежена кількість політик на проєкті. Та вона не буде значно збільшуватися в майбутньому.
  • Відсутність оновлення пермісій. Отримавши токен, користувач може довго залишатися в системі. Якщо протягом цього періоду пермісії зміняться, це ніяк не позначиться на токені та можливостях роботи із сервісом. Тобто якщо право на певні дії юзера вже відкликано, він все одно зможе їх виконувати.

Отже, продовжуємо пошуки далі…

Авторизаційний флоу з другим токеном

Оптимальним для нас варіантом виявилося додавання до системи ще одного токена. У такому разі після введення логіну та пароля у KeyCloak клієнт отримує з авторизаційним Bearer-токеном ще й JWT Auth Token.

Саме в ньому й міститься інформація про пермісії користувача (у межах одного продукту). Далі клієнт із парою токенів вирушає до будь-якого продукту, який сам і буде валідувати обидва «ключі»: окремо для авторизації та визначення прав юзера:


Маємо наступні переваги:

  • Відсутність дублювання. Як і в минулому сценарії, тут немає непотрібного копіювання даних та складної логіки.
  • Прив’язка пермісій до продукту. Окремий JWT Auth Token діє лише в одному продукті та не дублюється на весь сервіс.
  • Проста інтеграція в систему. Для впровадження такого механізму не потрібно змінювати авторизаційний флоу та писати окрему логіку для реплікування даних.
  • Онлайн-курс "Business English for Marketers" від Laba.
    Опануйте професійну англійську для маркетингу.Розширте карʼєрні можливості для роботи з іноземними колегами: від розробки нових продуктів до презентації стратегії бренду.
    Детальніше про курс

Недоліки у цього флоу теж були. Але ситуація виявилася некритичною через певні обставини:

  • Додатковий крок в авторизації. Необхідно додати механізм одержання користувачем другого токена. Втім, для модернізації флоу із KeyCloak нам так чи інакше довелося б писати нові логіки та інструменти. Цей варіант — ненайскладніший для реалізації з урахуванням його переваг.
  • Лаг під час оновлення пермісій. Це той самий ризик, що й у попередньому флоу. Але для нашого замовника це не проблема. Сценарії використання всіх трьох продуктів фармацевтичного сервісу припускають часте додавання прав користувачів, але рідше — позбавлення їх цих прав. Тому малоймовірна ситуація, коли користувача обмежили у можливостях, а він все одно має певні доступи. Якщо ж він отримує нові права з поточним токеном, то йому треба заново ввести логін і пароль. Тоді користувач матиме токен з оновленими пермісіями. Проблема як така не вирішується, та це не трагічно для цього проєкту.

Дизайн авторизаційного флоу

Врешті ми побудували авторизаційний флоу на основі останнього сценарію. Поступово ми адаптували цей варіант під особливості проєкту та наші технічні можливості.

Як зображено на схемі нижче, вся система складається з кількох основних елементів. Перший — це клієнт або UI. Також є авторизаційний сервер KeyCloak. За ним слідує Istio, який представляє Gateway Load Balancer. Для кешу передбачено Redis. Ще є User Service, котрий виконує роль згаданого Authorization Service, сховища для пермісій. Останнім тут іде Service — це решта сервісів, до яких надсилають запити на якусь інформацію.


Авторизаційний флоу організований у такий спосіб:

  • Користувач логіниться на авторизаційному сервері.
  • Далі виконує запит, припустимо, подивитися дані про пацієнта. Для цього Istio намагається отримати JWT-токен. Це виконує балансер, а не клієнт, що робить останній дуже легким.
  • Якщо запитаного балансером токена немає в Redis, цей ключ генерується та зберігається у кеш. Якщо ж такий токен в кеші наявний, він витягується у відповідь на запит від Istio.
  • Онлайн-курс "Предметний дизайн" від Skvot.
    Навчіться створювати функціональні, трендові та ергономічні дизайни меблів та предметів інтер’єру.
    Детальніше про програму курсу і лекторів
  • Після цього JWT-токен додається в хедери запиту, і виконується запит на отримання потрібної користувачеві інформації.

Зауважу, що у нашому проєкті ця система імплементована не до кінця, оскільки поки що немає процесу кешування другого токена. Але ми додамо це в майбутньому і доведемо процес до ідеалу.

Проєкт №2

Тут ми маємо справу з багаторічним legacy-проєктом. У певний момент знадобилося перенести його на Azure. У цьому випадку центральна частина — це Image Service, сховище зображень користувачів. Вони можуть завантажувати картинки та фотографії, переглядати та редагувати їх. Клієнтами виступають два елементи: вебклієнт і десктопний застосунок. 

Для прикладу я розгляну механізм авторизації при додаванні користувачем зображень.

Авторизаційний флоу в legacy-проєкті

Початкова авторизація в Image Service зроблена просто. При спробі завантажити зображення до сховища в тілі запиту надсилалися три поля: спеціальний ключ та Поле 2 і Поле 3.

Перший ключ — єдина для всіх користувачів і системи GUID-стрінга. Вона виконувала роль валідації за користувачем і його запитом. Поле 2 та Поле 3 допомагали для аутентифікації та використовувалися для групування картинок у папки:

Ця система мала багато ризиків:

  • Один спеціальний ключ на систему. У випадку його крадіжки буде скомпрометовано весь сервіс.
  • Онлайн-курс "Створення особистого бренду" від Skvot.
    Прокачайте особистий бренд для підсилення власного бізнесу, підвищення продажів та впізнаваність на ринку.
    Дізнатись більше про програму курсу і досвід лектора
  • Статичні параметри. Вказані параметри для додавання картинок не динамічні. Це обмежує функціонал і знижує безпеку.
  • Нестандартний протокол. Флоу виконаний не за звичними канонами, не покриває всіх аспектів безпеки та може викликати питання у нових розробників.

Хоча в цілому система працювала і влаштовувала замовника… Допоки не постало питання міграції завантажень та зберігання зображень на Azure. З основною частиною функціоналу було зрозуміло: ми частково перевикористовували логіку з легасі-системи. Але авторизаційний флоу варто було покращити.

Міграція фіч на Azure

Для контексту коротко розкажу про саму міграцію. Під час завантаження фотографій Azure спілкується з легасі-системою для збереження певних метаданих.

Тому була спокуса залишити все як є, а валідувати потім. Від цієї ідеї ми відмовилися, оскільки в планах замовника вже були зміни авторизації за всіма підпроєктами.

Ключовим же фактором було збереження клієнтів під час міграції на Azure. Згадані вебклієнт та десктопний застосунок не змінювали своїх контрактів, логіки та процесів. Зміни могли торкатися лише Subscription Key і не більше. Тому наша команда створила відразу два рішення: проміжне для «тут і зараз» і більш далекоглядне:


Дизайн авторизаційного флоу

На сьогодні для авторизації на Azure ми використовуємо API Management. Ця система може проксіювати запити та оголошувати сценарії виконання. Тобто в якій послідовності додавати дані або хедери, як модифікувати запити тощо. Причому першим кроком у API Management є отримання JWT-токена. Це відбувається за тими ж полями, які спочатку були в легасі-проєкті. Єдиний виняток — Subscription Key. Ми позбулися його і додали свій ключ, який може бути динамічним.

Валідує його безпосередньо API Management:

Після отримання JWT-токену система передає в ажурівську Auth Function параметри для авторизації користувача. Йдеться про згадані вище Поле 2 та Поле 3. За цими значеннями функції й відбувається вилучення JWT-токена з Redis, якщо раніше він був там розміщений.

Онлайн-курс "QA Automation" від robot_dreams.
Це 70% практики, 30% теорії та проєкт у портфоліо.Навчіться запускати перевірку сотень опцій одночасно, натиснувши лише одну кнопку.
Детальніше про курс

Якщо ж токена у сховищі немає, виконується запит до легасі-системи з Image Service щодо валідності запиту за вказаними параметрами. У разі підтвердження генерується новий JWT-токен. Потім він розміщується в Redis, а звідти повертається до API Management.

Як працює API Management

На цьому моменті хочу зосередитись детальніше. Після отримання токена та його збереження у хедері API Management валідує ключ за своїми параметрами. Чому це важливо? Ось це і є наше рішення на майбутнє. З такою логікою ми підготувалися до моменту, коли API Management завжди валідуватиме хедер та JWT-токен. Наступним кроком стане виклик функції додавання картинки в систему. Можливо, на нинішньому етапі розвитку проєкту та його міграції це зайва робота для розробника. Та в майбутньому нам буде набагато менше переробляти.

Аби краще пояснити ідею, покажу приклад коду з API Management. Система описується простим XML-файлом:

Тут є перша перевірка, де з реквесту з хедерів дістається Subscription Key. Це саме те, що валідує сам API Management. Він його порівнює зі своєю змінною оточення. У нашому випадку це якраз згенерований самим API Management ключ. Тобто він перевіряє, чи є такий ключ у запиті. Якщо є, система переходить до наступного кроку — send-request:

Запит надсилається до Auth Function для отримання JWT-токена. Для цього створюється запит та передається тіло з необхідними параметрами. А далі функція повертає або закешований, або згенерований токен. Його природа не важлива — важливе повернення функцією цього ключа:

Потім цей токен із доповненням Bearer зберігається. Тут доступний такий функціонал, як set-header до запиту. Завдяки цьому ми можемо сетити загальноприйнятий хедер Authorization для Bearer-токена:

Курс Fullstack Web Development від Mate academy.
Стань універсальним розробником, який може створювати веб-рішення з нуля.
Дізнатись про курс

З’являється validate-jwt, який дозволяє валідувати авторизаційний токен, створений на попередньому етапі. В разі успішної валідації запит надсилається вже до Azure Function:

Зверніть увагу: все це виконується тільки для десктопного застосунку. Вебклієнт цього не вимагає — там і так безпечний канал спілкування. Далі залишається виконати запит:

Рішення може здатися досить складним. Адже треба додавати генерацію токена, валідацію тощо. Та ці дії цілком виправдані. Коли в майбутньому замовник зможе сам користуватися певним авторизаційним сервером для отримання Bearer-токену, достатньо буде вилучити зі схеми ці два кроки (виділені на скріншоті):

А далі — оновимо API Management, і на цьому модернізація системи, яка мігрувала до Azure, закінчиться. Все готово до змін у вигляді самостійної авторизації клієнтом за допомогою JWT-токену.


Наведені приклади — це доказ того, що авторизаційний флоу може бути дуже різним. Тому завжди ретельно досліджуйте свій проєкт, намагайтесь зрозуміти, який спосіб авторизації буде найоптимальнішим для конкретного випадку.

Курс QA від Mate academy.
Найпростіший шлях розпочати кар'єру в ІТ та ще й з гарантованим працевлаштуванням.
Інформація про курс

Якщо ви знайшли помилку, будь ласка, виділіть фрагмент тексту та натисніть Ctrl+Enter.

Онлайн-курс "Business English" від Laba.
Вивчіть базу граматики, лексики та вокабуляру.Використовуйте англійську в спонтанній розмові з колегами та клієнтами.Прокачайте її до впевненого В1 — для розвитку кар’єри в бізнесі.
Приєднатись до курсу

Цей матеріал – не редакційний, це – особиста думка його автора. Редакція може не поділяти цю думку.

Топ-5 найпопулярніших блогерів березня

PHP Developer в ScrumLaunch
Всего просмотровВсього переглядів
2434
#1
Всего просмотровВсього переглядів
2434
Founder at Shallwe, Python Software Engineer (Django/React)
Всего просмотровВсього переглядів
113
#2
Всего просмотровВсього переглядів
113
Career Consultant в GoIT
Всего просмотровВсього переглядів
95
#3
Всего просмотровВсього переглядів
95
CEO & Founder в Trustee
Всего просмотровВсього переглядів
94
#4
Всего просмотровВсього переглядів
94
Рейтинг блогерів

Найбільш обговорювані статті

Топ текстів

Ваша жалоба отправлена модератору

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: