Авторизація та автентифікація за технологією Single Sign On дуже поширені в сучасних IT-продуктах. Усе більше сервісів інтегрується один в одного, і перехід між ними без повторного вказання логіну та паролю спрощує життя користувачам. Однак для розробників не все так просто. Інструментів Single Sign On багато, й який із них кращий важко сказати. Спробуймо порівняти й обрати серед популярних провайдерів — IdentityServer 4, Azure B2C та Keycloak.
Як працює Single Sign On
Для початку пройдемося по базовій теорії. Single Sign On — це технологія єдиного входу. Вона спрощує для користувача роботу із різними сервісами. Юзер може 1 раз пройти процедуру ідентифікації і переміщатися між сервісами без постійного введення різних логінів та паролів. Всі перевірки кожного разу будуть здійснюватися непомітно для користувача, під капотом системи. Найкращий приклад використання цієї технології — екосистема Google. Ви вводите пароль, а потім без постійного повторення кредів користуєтеся Google Docs, Google Disk, Google Photos тощо. При цьому за своїм Google-акаунтом можна зайти навіть до сторонніх сервісів, які підключили цей функціонал для авторизації та автентифікації.
Принцип технології Single Sign On можна оцінити за наступною схемою. Користувач відкриває браузер і намагається зайти на перший сайт. Сайт звертається до ID-провайдера, з яким встановлені довірчі відносини і який ми налаштували раніше. Для звернення сайт використовує ключ, за яким йде валідація всієї інформації.
Користувач створює запит на сайті №1 на певні дані, але той в такому випадку вимагає пройти автентифікацію. Для цього сайт створює у браузері користувача редирект на Identity-провайдер, де можна отримати потрібну інформацію про права користувача. ID-провайдер переконується, що по цьому запиту відсутня інформація та він не знає користувача, а тому повертає в браузер свою логін-сторінку. Там юзер указує креди, і провайдер перевіряє їх. Як тільки сервіс «впізнає» користувача і виконає авторизацію, він поверне сайту через браузер спеціальний токен. Сайт валідує токен і надасть юзеру доступ до ресурсів відповідно до його ролі. При цьому користувач непомітно для себе отримає ще й cookies. Саме вони спростять взаємодію юзера та цього сайту, а також усіх інших, де підключено цього конкретного Identity-провайдера.
Також уявімо ще один сайт в цій системі. Він також вимагає від юзерів автентифікацію та авторизацію, і у цього сайту встановлені довірчі відносини з тим самим Identity-провайдером. Ситуація ніби повторює відправку запиту. Але є відмінність: Identity-провайдер знає, що користувач вже пройшов ідентифікацію. Тож не треба передавати логін-сторінку, а достатньо лише повернути другий токен сайту. І тоді останній віддасть юзеру потрібний ресурс, а також для подальшої роботи створить свої cookies.
Цей підхід має дві переваги:
- Зручність використання. Користувач логіниться лиш раз та отримує доступи до ресурсів на усіх потрібних йому сайтах без регулярних редиректів на якісь логін-сторінки.
- Простий менеджмент. Керування доступами може бути централізованим. Ми налаштовуємо доступи та ролі юзерів, скоупи ресурсів та усі інше буквально в одному місці.
Та є й певні проблеми у цьому підході до авторизації та автентифікації. При викраденні даних користувача хакери отримують доступи до всіх акаунтів на різних сайтах, де був зареєстрований наш юзер. Втім, на цю ситуацію можна подивитися трохи з іншого боку. Усі системи можна взламати. Адже користувачі часто не ускладнюють собі життя при виборі паролю. В багатьох випадках вони придумують досить легкий пароль, інколи лише додають до нього певні символи. Про випадки з єдиним паролем до всіх сайтів і казати годі... Тож ризики є завжди. Просто треба розуміти, заради чого ви використовуєте нову модель.
Варіанти реалізації flow за технологією OAuth 2.0
Існує багато протоколів для налаштування автентифікації та авторизації: OpenID Connect, OAuth 2.0, SAML, WSFed. В статті будуть розглянуті лише два перші як найбільш поширені.
OpenID Connect є надбудовою над OAuth 2.0 та дозволяє верифікувати юзерів за допомогою авторизаційних серверів. Можна підключати різні клієнти (зокрема й на JavaScript для отримання даних про сервіси), десктопні та веб-застосунки — все для як автентифікації, так і для авторизації. Щодо до OAuth 2.0, то цей протокол відповідає за перевірку доступів юзерів. У нього є декілька flow для реалізації механізму авторизації. Останній буде вказувати, де та яку конкретно інформацію брати, а також що і де зберігати.
Client Credentials Flow. Також цей флоу називають Machine to Machine або Service to Service. Він допомагає налаштувати автентифікацію і авторизацію між різними сервісами, при цьому без взаємодії з власне юзером. Побудова цього флоу — на наступній схемі.
Device Authorization Flow. Цей флоу призначен для застосунків, що мають працювати ще на декількох пристроях. Наприклад, він підходить для Smart TV, де є застосунки для стрімінгових платформ, YouTube, відео через торенти тощо. В такому випадку автентифікація — це дійсно часте завдання в різних сервісах. При цьому вони мають зберігати дані про перегляди юзерів та на їх основі готувати рекомендації. І тут вже потрібна авторизація — це те, без чого не буде працювати основний функціонал цих застосунків.
В цьому випадку такий пристрій повинен якось з’єднатися із Identity-провайдером для ідентифікації користувачів. Через це процес значно ускладнюється, адже сторонній пристрій може бути позбавлений браузера як такого. Тож тут використовується браузер-флоу. Із ним авторизація може проходити, наприклад, через смартфон, коли користувач вводить дані на екрані свого пристрою. Реалізація такого механізму — на наступній ілюстрації.
Implicit Flow. Цей механізм допоможе отримати клієнтську частину від Access-токенів та Refresh-токенів. Його можна досить швидко реалізувати, проте рівень безпеки не дуже високий. В цьому випадку ми передаємо токени на клієнта, і він може зберігати їх у будь-який спосіб та при авторизації приходити з конкретним токеном для отримання інформації. Саме через це немає впевненості у безпеці токенів. Тому цей флоу можна застосувати тільки за гарантій сек’юрності мережі, де виключені ризики потрапляння зловмисника в середину процесів.
Authorization Code Flow. Цей механізм автентифікації завдяки його безпеці можна використати як альтернативу до Implicit Flow. Треба лише пам’ятати: клієнтська частина тут знає Client ID та Client Secret. Проте взаємодія побудована на застосуванні Authorization-коду, рандомно згенерованого коду, тож все має бути нормально. Стандартна рекомендація стосовно цього флоу: використання для сервер-сайт застосунків (наприклад, застосунку ASP.NET MVC). А головне: навіть із сторонніми бібліотеками потрапити в те, що генерується сервером, буде дуже складно.
Authorization Code Flow with Proof Key for Code Exchange (PKCE). Це варіант минулого флоу із певними удосконаленнями. Механізм передбачає рандомну генерацію Code Verifier та Code Challenge. Авторизація тут проходить із Code Challenge. Після отримання кредів від юзера віддається Authorization Code. Далі для отримання токена потрібно використати щойно виданий Authorization Code та Code Verifier. Завдяки цьому валідація в Identity-провайдері відбувається на основі одразу трьох кодів. А тому якщо хакер отримає один із кодів, це не буде проблемою. Такий флоу можна встановити, наприклад, у таких Single Page Applications, як Angular- та React JS-програмах або нативних застосунках на Android та iOS.
Hybrid Flow. В цьому механізмі об’єднано Implicit Flow та Authorization Code. За задумом авторів, такий флоу більш складний, а тому й трохи безпечніший. Проте він фактично має позитивні та негативні характеристики обох більш простих флоу.
Переваги та недоліки популярних Identity-провайдерів
IdentityServer 4
У ньому реалізована підтримка протоколів OpenID Connect і OAuth 2.0 та сторонніх Identity-провайдерів. Також є декілька варіантів того, як підключається авторизація. Це можливо за допомогою акаунтів у Google, Facebook, Microsoft, Twitter, Instagram тощо. Розгортання доволі легке. Для цього створюється застосунок і встановлюються Nuget-пакети з IdentityServer4, IdentityServer4.EntityFramework та IdentityServer4.AspNetIdentity та пакет IdentityModel на клієнтську частину (якщо, припустимо, MVC-застосунок як клієнт). Це допоможе отримати дані про Access-токени і там же, під капотом, редиректити запити у потрібний спосіб.
У цього провайдера є декілька плюсів:
- Гнучкість при налаштуванні і доступність кастомних валідаторів. Через те, що ми самостійно створюємо застосунок із встановленими Nuget-пакетами, можна також власноруч перевизначити, наприклад, валідацію токенів. Це може знадобитися для додаткових перевірок.
- Створення UI. Ви можете розробляти користувацький інтерфейс для сторінок реєстрації, логін-сторінок, акаунтів тощо. Також є виконання від самого провайдера, та ця реалізація не завжди доречна. Саме тому IdentityServer 4 йде без UI — так ви можете образу створити свій інтерфейс.
- Підтримка flow. Цей провайдер підтримує розглянуті вище флоу: Auth Code, Device Flow тощо.
- Якісна документація. Її розробляє велике ком’юніті. Тож ви зможете швидко познайомитися з функціоналом та підключити все, що вам потрібно.
- Працює із CloudBase та On-Premise рішеннями. Але треба пам’ятати, що треба власноруч дбати про спосіб розгортання у хмарах.
- Безкоштовно навіть для комерційних задач.
Недоліки IdentityServer 4:
- Високий поріг входження. Для його налаштування треба добре розумітися на авторизації і автентифікації, їх механізмах.
- Відсутність адміністративної панелі. Задля побудови робочої системи із багатьма доступами потрібно прикласти чимало зусиль. Адміністратор може запросити звичний UI для вибору та зберігання потрібного функціоналу.
Azure B2C
У цьому Identity-провайдері є підтримка тих же протоколів, як у IdentityServer 4, зовнішніх провайдерів, а ще SAML. Є декілька користувацьких флоу за замовчуванням: Sign in, Sign up, Edit Profile, Password Reset. Плюс провайдер підтримує мультифакторну автентифікацію і управління доступами юзерів.
Для інсталяції та налаштування Azure B2C знадобиться підписка на Azure. Також треба буде створити B2C Tenant ресурс та зареєструвати API і клієнтів із App registrations. А потім для підключення потрібен ще Nuget-пакет у вигляді Microsoft.Identity.Web. Все це дозволить запустити все із коду.
На наступній ілюстрації ви можете оцінити зовнішній вигляд адмін-панелі Azure B2C і функціонал App registrations. В якості прикладу тут створено API разом з двома клієнтськими програмами. Для цього тут створюється список, в якому можна знайти додаткову інформацію: як підключитися до програм, які доступні ID та скопи. Плюс можна додавати інші реєстрації.
У лівій частині розміщено меню Identity-провайдерів, де можна додавати зовнішні рішення для побудови авторизації. Також передбачено меню для юзерів і для ролей із деталізованою статистикою. Ми можемо отримати інфу, як часто користувачі заходять у систему та про їх взаємодію з нею. А ще треба акцентувати увагу на User Flow. Для прикладу тут обрано два варіанти, що було створено за декілька кліків та встановлено в Azure B2C. Тобто все дуже просто: ви можете легко занурюватися в конфігурацію, змінювати налаштування тощо.
В Azure B2C є кілька переваг:
- Проста конфігурація основних користувацьких флоу.
- CloudBase-рішення.
- Доступний з коробки User management.
- Зручний інтерфейс. Ви можете налаштовувати сторінки та будь-які дані юзерів. Також можна установити власні стилі для цілісності дизайну із вашою системою.
- Легкий старт. Запуск організовується в невелику кількість коду. Налаштування на Azure-порталі відбуваються швидко, як і підключення в застосунку.
- Середній поріг входження.
Але маємо й недоліки:
- Витрати. По-перше, треба оплатити підписку на Azure. По-друге, треба доплатити за користування сервісом, якщо протягом місяця більше 50000 користувачів. По-третє, платною є і мультифакторна автентифікація (це ще й зі своїм терміном використання).
- Складні налаштування флоу. У цьому провайдері необхідно створювати Custom Policy та працювати з конфігураціями XML навіть для заміни основних flow. Наприклад, це треба для додавання валідації.
- Не відповідає On-Premise рішенням. Розгортати Azure B2C можна тільки в хмарі. Але ці рішення нерідко встановлюються у системах без доступу до інтернету.
Keycloak
Цей провайдер також підтримує основні протоколи для автентифікації та авторизації: OpenID Connect, OAuth 2.0 і SAML. Є і зовнішні провайдери, і встановлені флоу. А ще доступна підтримка LDAP і Active Directory. Вони допоможуть інтегрувати юзерів із інших систем. Плюс за замовчуванням є керування користувачами і доступами для них.
Це рішення написане на Java. Але з огляду на поширеність кросплатформеності, яскравим представником якої є .NET Core, його можна спробувати інтегрувати з іншою мовою. Тож як сервіс Keycloak надається за допомогою кількох майданчиків: Kubernetes, Openshift, Podman та Docker. І при роботі, наприклад, з останнім немає якихось проблем. Для завантаження пакетів, їх установки та запуску достатньо однієї команди.
Базове налаштування флоу авторизації в Keycloak проходить за наступним планом:
- Створення реальності. Це відповідає поняттю Tenant в Azure B2C. Мається на увазі область чи група, в які можна додати сам застосунок.
- Додавання клієнтів. Мова йде про програми, які потрібні в цій системі.
- Додавання конфігурацій для програм.
- Створення скоупів.
- Створення ролей.
На наступній ілюстрації зображено адмінпанель Keycloak. В ній наведено перелік усіх клієнтів у системі. За замовчуванням вже є клієнт, який було створено як частину самого сервісу. Але у прикладі також є зареєстрований демо-застосунок.
В меню програми є дуже багато можливостей для конфігурації. Наприклад, тут зібрано стандартні Client-скоупи авторизації та автентифікації: e-mail, профайл, ролі. Також можна додавати та підключати на застосунки й свої скоупи. А в лівій частині меню можна знайти багато корисної інформації про ролі, Identity-провайдерів, користувачів, сесії тощо.
До позитивних характеристик Keycloak відносяться:
- Гнучкість налаштувань програм і доступів.
- Адміністративна панель. У провайдера вже є декілька конфігурацій для UI. Для налаштувань доступів не треба занурюватися в конфіг-файли. Для цього достатньо обрати та зберегти потрібні пункти, що може виконати навіть адмін програми.
- Формат Stand-alone. Застосунок самостійно хоститься і готовий до роботи — його не треба розгортати окремо.
- Підтримує Cloud та On-Premise рішення.
- Безкоштовний сервіс.
Щодо недоліків Keycloak, то основними є:
- Високий поріг входження. Величезна кількість налаштувань потребує досвіду, аби розібратися в коригуваннях системи.
- Відсутність офіційних бібліотек для .NET Core. Втім, можна інтегруватися із провайдером завдяки пакету Microsoft.AspNetCore.Authentication.JwtBearer, який є стандартним у .NET Core.
Що обрати для автентифікації та авторизації
Наприкінці треба порівняти основні особливості цих трьох популярних сервісів для авторизації і автентифікації. Це спростить вибір оптимального варіанту саме для вашого проєкту.
- Підтримка протоколів. Фактично однакова в усіх сервісах.
- Фінансова складова. Програш Azure B2C через оплату підписки та активності юзерів.
- .NET Core. У цій частині аутсайдером є Keycloak.
- Менеджмент. В IdentityServer 4 можна самостійно реалізувати управління ролями безпосередньо в коді. В Azure B2C це все виконується через Access Policy. Хоча роль-менеджмент в Azure-порталі поширюється виключено на цей портал, але не на додані програми. А в Keycloak є переваги обох провайдерів. З одного боку, можна використовувати ролі для передачі юзеру доступів до сторінки користувача, хостинг якої на боці самого Keyclock. З іншого ж, можна додавати ролі на ресурси та юзерам. Завдяки цьому додавання і налаштування ролей більш гнучке.
- Налаштування. Найбільш складним є Azure B2C. Базові варіанти в ньому є досить простими, але будь-які нестандартні задачі вирішити складно.
Неможливо сказати, який флоу чи Identity-сервер кращий. Ба більше, можна не обмежуватися лише переліченими у статті варіантами. Тож раджу порівнювати всі рішення для побудови як автентифікації, так і авторизації та враховувати особливості вашого проєкту.
А наостанок — ловіть офіційну документацію перелічених провайдерів та читайте про кожен детальніше:
• Keycloak.