Теорія OAuth 2.0: Поняття, Аналогії та Флоу
Теорія OAuth 2.0: Поняття, Аналогії та Флоу
Проблема: Синдром «Ключа від усіх дверей»
Уявіть, що ви приїхали в розкішний готель на своєму автомобілі. Біля входу вас зустрічає паркувальник (valet). Ви хочете, щоб він відігнав вашу машину на парковку.
До появи сучасних систем доступу, у вас був лише один варіант: віддати паркувальнику свій єдиний, головний ключ від машини. Що це означає на практиці? Разом із можливістю просто завести двигун і проїхати 100 метрів, ви також дали йому можливість:
- Відкрити багажник, де лежать ваші цінні речі.
- Відкрити бардачок з документами.
- Поїхати на вашій машині в інше місто (ключ же повноцінний!).
В інтернеті початку 2000-х веб-сервіси працювали саме так. Якщо ви хотіли надрукувати свої фотографії з Flickr через сторонній сервіс друку, цей сервіс просив вас: "Будь ласка, введіть свій логін і пароль від Flickr". Ви віддавали свій "головний ключ". Сервіс друку міг не лише завантажити фотографії, але й видалити їх, змінити ваш пароль або написати коментарі від вашого імені. Ви змушені були безмежно довіряти повністю чужому сервісу.
Це був архітектурний кошмар безпеки. Саме для розв'язання цієї проблеми був створений OAuth 2.0.
Валет-ключ (Valet Key): Як працює OAuth 2.0
Автомобільна індустрія вирішила проблему паркувальників елегантно: винайшли Valet Key (валет-ключ). Це спеціальний, обмежений ключ. Він може лише завести двигун і відкрити двері водія. Він не може відкрити багажник або бардачок, і машина може проїхати на ньому не більше 5 кілометрів.
OAuth 2.0 (Open Authorization) — це цифровий "валет-ключ" для інтернету.
Це стандарт делегованої авторизації. Він дозволяє вам надати одному застосунку (наприклад, сервісу друку) обмежений доступ до ваших ресурсів на іншому сервісі (наприклад, у Google Photos) без передачі вашого пароля. Замість пароля сервіс отримує спеціальний "валет-ключ" — Access Token (Токен Доступу).
1. Головні учасники (Актори)
Щоб зрозуміти протокол, потрібно познайомитися з його учасниками. Уявіть, що ви (Власник) хочете, щоб Сторонній Застосунок (Наприклад, планувальник подорожей) міг іноді читати ваші події в Google Календарі.
1. Resource Owner (Власник ресурсу)
2. Client (Клієнт)
3. Authorization Server (Сервер Авторизації)
4. Resource Server (Сервер Ресурсів)
2. Аналітичний розбір понять: Токени та Scopes
Тепер подивимось на те, з чим працюють ці учасники.
Scopes (Області доступу)
Scope — це список обмежень, викарбуваний на "валет-ключі". Коли Клієнт приходить до Сервера Авторизації, він каже: "Мені потрібен доступ до календаря, контактів і щоб я міг відправляти листи". Це і є Scopes (області).
Коли Сервер Авторизації питає вас (Власника): "Цей додаток хоче читати ваші листи. Дозволяєте?" — ви бачите саме ці Scopes. Якщо ви погоджуєтеся, Сервер Авторизації записує ці дозволи (і ТІЛЬКИ ЇХ) у токен. Якщо Клієнт спробує видалити лист, Сервер Ресурсів подивиться на токен і скаже: "Тут написано тільки 'читання'. Відмовлено."
Access Token (Токен доступу)
Це і є сам "валет-ключ". Цифровий бейдж, який Клієнт показує Серверу Ресурсів. У світі OAuth він часто має вигляд довгого набору символів (JWT). Важлива деталь: Access Token має короткий термін дії. Часто від 5 до 60 хвилин. Чому? Бо якщо цей ключ хтось вкраде, краще, щоб він перетворився на гарбуз якомога швидше.
Refresh Token (Токен оновлення)
Але якщо Access Token живе лише 15 хвилин, чи потрібно Користувачу кожні 15 хвилин вводити пароль знову? Ні. Для цього існує Refresh Token. Це сертифікат на отримання нового валет-ключа.
Якщо Access Token — це перепустка гостя на територію, яка "згоряє" ввечері, то Refresh Token — це секретний талон, який гість (Клієнт) може непомітно показати охороні (Серверу Авторизації) і без вашої участі отримати новеньку перепустку на завтра. Оскільки Refresh Token дуже потужний, Клієнт надійно ховає його і ніколи не показує Серверу Ресурсів.
3. Глобальне непорозуміння: Авторизація vs Аутентифікація
Тут ми маємо зупинитися і розставити крапки над «і» у найпоширенішій плутанині сучасної IT-безпеки.
- OAuth 2.0 — це протокол АВТОРИЗАЦІЇ (Authorization). Він відповідає на питання "Чи має право цей застосунок відкрити цей файл?".
- OpenID Connect (OIDC) — це протокол АУТЕНТИФІКАЦІЇ (Authentication). Він відповідає на питання "Хто зараз сидить перед екраном?".
Аналогія з готелю:OAuth 2.0 — це видача електронної картки гостя. На ній не написано ваше ім'я або стать. Там написано: "Може відкрити двері 402, може ходити в басейн з 8:00 до 20:00". Для дверей басейну неважливо, як вас звати — важливо, чи є у цій картці доступ. OpenID Connect — це ваш паспорт або бейдж з фотографією. Там написано: "Це Іван Петренко, йому 30 років". Охорона дивиться на паспорт і розуміє, з ким має справу.
Коли OAuth 2.0 був створений, люди почали "ламаючи" його, використовувати для того, щоб дізнаватися "хто залогінився". Щоб стандартизувати це, індустрія створила OpenID Connect — надбудову поверх OAuth 2.0. OIDC робить лише одну річ: окрім "валет-ключа" (Access Token), він зобов'язує Сервер Авторизації видати ще й спеціальний ID Token.
ID Token — це "цифровий паспорт", який Клієнт може прочитати і сказати: "Ага, тебе звати Іван, і ось твій email".
4. Види потоків авторизації (OAuth 2.0 Flows / Grants)
Як саме Клієнт отримує токен? Цей процес називається "Grant Type" або "Flow". Існують різні потоки (маршрути) отримання токена, залежно від того, яким є Клієнт (це серверний застосунок, мобільна гра, телевізор чи розумний холодильник).
Уявіть, що Охорона (Сервер Авторизації) має кілька різних інструкцій щодо того, як видавати ключі для різних типів відвідувачів.
Аналогія: Здача посилки в постамат за секретним кодом. Ви замовили цінний пакунок у відділення (Сервер Ресурсів), і хочете відправити туди кур'єра (Клієнта), щоб той його забрав. Але кур'єр — людина чужа (сторонній сервер). Ви не можете просто віддати йому свій паспорт. Ви заходите на сайт служби доставки, підтверджуєте свою особу своїм паролем, і банк видає вам ОДНОРАЗОВИЙ ПАПІРЕЦЬ з коротким кодом (Authorization Code). Ви даєте цей код кур'єру. Кур'єр їде до відділення і ОБМІНЮЄ цей короткий код на саму посилку (Access Token), ПЛЮС показує свій власний паспорт кур'єра (свій Client Secret), щоб довести, що він саме той, кому видоручили це зробити.
Як це виглядає технічно:
- Клієнт направляє вас (користувача) у браузері на сторінку Сервера Авторизації (наприклад, сторінку логіну Google).
- Ви вводите пароль від Google. Клієнт не бачить ваш пароль (це відбувається на сайті Google).
- Після вашої згоди, Google каже вашому браузеру: "Перенаправ його назад до Клієнта і передай у посиланні короткочасний рядок
code=12345". - Браузер приносить цей
codeна сервер Клієнта. - Сервер Клієнта (невидимо для вас) звертається до Google, показує цей
codeТА свій власний пароль сервісу (Client Secret), і отримує реальнийAccess Token.
Чому саме так? Тому що браузер (ваш комп'ютер/телефон) — це небезпечне місце. Якщо передати справжній повноцінний Access Token відразу в браузер — його можуть вкрасти злісні розширення або скрипти. А короткий одноразовий code марний для хакера, бо щоб обміняти його на токен, потрібен ще серверний пароль Клієнта (Client Secret), який лежить у безпеці на бекенді Клієнта.
Аналогія: Отримання посилки кур'єром, який втратив паспорт.
Ситуація як у попередньому пункті, але є проблема: додаток живе у вашому телефоні (Mobile App) або виконується прямо в браузері (Single Page Application — React/Angular). Такий Клієнт не має безпечного бекенд-сервера, щоб заховати там свій пароль (Client Secret). Якщо «зашити» пароль у код мобільного додатку, хакери легко дістануть його. Отже, такий Клієнт не зможе довести Охороні, що він — це він, бо в нього немає паспорта.
Вирішення (PKCE — Proof Key for Code Exchange): Кур'єр прямо перед тим, як просити код, каже: "Я загадав слово 'ЯБЛУКО', але тобі скажу тільки його зашифровану версію 'ХХХ'. Коли я прийду обмінювати код на токен, я скажу тобі оригінальне слово 'ЯБЛУКО'. Якщо воно збігається з шифром — значить, я це справді я".
Як це працює технічно:
- Застосунок динамічно (на льоту) генерує гігантський випадковий пароль (Code Verifier) і рахує з нього хеш (Code Challenge).
- Разом із запитом до Сервера Авторизації він надсилає цей хеш.
- Коли застосунок повертається з коротким
codeобмінювати його на токен, він надсилає ОРИГІНАЛЬНИЙ випадковий пароль (Code Verifier). - Сервер рахує хеш з оригніалу, і якщо він збігається з тим, що йому надіслали на початку — він видає Access Token, знаючи, що це точно той самий застосунок, що і починав запит (бо перехопити динамічний
code, та ще й вгадати оригінальне випадкове слово сторонній програмі на телефоні майже неможливо).
Аналогія: Кинути ключі з балкона просто в натовп.
У старих веб-застосунках браузери мали обмеження — вони не могли робити фонові запити до інших доменів безпечно. Тому придумали "спрощений поточний варіант".
Замість одноразового папірця з кодом (code), Сервер Авторизації після вашого логіну одразу клав справжнісінький, повноцінний Access Token прямо в URL браузера: site.com/callback#token=СЕКРЕТНИЙ_КЛЮЧ.
Це було жахливо з точки зору безпеки. Будь-хто, хто стояв за спиною і дивився на ваш екран, будь-який шкідливий скрипт на сторінці або історія браузера — усі бачили повноцінний токен доступу. Сьогодні цей флоу вважається застарілим і вкрай небезпечним. Його повністю замінив "Authorization Code Flow with PKCE" (пункт 2).
Аналогія: Ділова зустріч двох компаній (B2B). Ваша присутність не потрібна. Уявіть, що ви (Власник) тут взагалі не берете участі. Застосунок «А» ("Сервіс Рахунків") хоче відправити дані Застосунку «Б» ("Сервісу Статистики"). Їм не потрібно запитувати дозволу у вас як у користувача, оскільки вони звертаються до загальних системних даних, а не до ваших фотографій.
Сервіс «А» бере свій логін та пароль (Client ID та Client Secret), йде до Бюро Перепусток (Сервера Авторизації) і каже: "Я сервіс Рахунків. Ось мої документи. Видайте мені бейдж на вхід у Сервіс Статистики". Сервер Авторизації видає Access Token. Усе відбувається миттєво і виключно між серверами, без браузерів та редіректів.
Аналогія: Віддати пароль від свого банківського додатку баристі в кав'ярні, щоб він сам зняв гроші за вашу каву. У цьому потоці Клієнт просить вас прямо в у свій власний інтерфейс ввести ваш логін і пароль від стороннього сервісу (наприклад, Facebook). А потім він просто пересилає ваші логін та пароль на сервер Facebook, щоб отримати Access Token.
Чому це існує? Це було створено як "перехідний місток" для стародавніх застосунків, які ще не вміли відкривати браузери для перенаправлення користувача. Чому це жахливо? Ви порушуєте головне правило OAuth: Ніколи не віддавати свій пароль сторонньому додатку! Додаток може зберегти ваш пароль у свою базу даних, або випадково злити його. OAuth 2.1 (новий стандарт) пропонує повністю заборонити і видалити цей потік.
Аналогія: Додзвонитися в банк з розумної колонки, але підтвердити операцію через додаток на телефоні. Ви купили Smart TV. Ви намагаєтесь увійти в застосунок Netflix. Але вводити пароль пультом — тортури. А у телевізора часто взагалі немає повноцінного захищеного браузера для перенаправлень. Охорона (Сервер Авторизації) не може працювати за старими схемами.
Як це працює:
- Телевізор іде до Сервера Авторизації і каже: "Тут людина хоче увійти, але в мене немає клавіатури".
- Сервер повертає великий, красивий код: "ABCD-1234".
- Телевізор малює цей код на половину екрану і пише: "Візьміть свій смартфон, відкрийте сторінку
netflix.com/linkі введіть цей код". - Ви на своєму зручному смартфоні (де ви вже можливо залогінені) заходите на цю сторінку, вводите "ABCD-1234".
- Тим часом телевізор кожні 5 секунд нишком стукає до сервера: "Він вже ввів? Ні? А зараз? Ні?".
- Щойно ви ввели код на смартфоні і натиснули "Дозволити", телевізор під час наступного "стуку" замість відмови отримує повноцінний Access Token і відео запускається! Застосунок на телевізорі жодного разу не бачив і не просив ваш пароль!
Резюме: Правило трьох "Так"
OAuth 2.0 та OIDC стають простими і логічними, якщо прийняти їхню філософію:
- Пароль користувача — святий. Сторонній застосунок (Клієнт) ніколи, за жодних обставин, не повинен його бачити або тримати у себе в пам'яті. Користувач вводить пароль лише на сторінці тієї системи, якій належить пароль (Authorization Server).
- Токени тимчасові, права обмежені. Клієнт завжди отримує мінімальний необхідний рівень доступу (Scopes) і на обмежений час (Access Token + Refresh Token). Якщо ви дозволили додатку читати листи, він не зможе їх надіслати.
- Середовище визначає маршрут. Як застосунок отримує токен (Flow), залежить тільки від рівня його безпеки. Є сейф (бекенд) — використовується Authorization Code; немає сейфа (мобільний або SPA) — PKCE; немає браузера і клавіатури (Smart TV) — Device Code; немає людини (сервіс) — Client Credentials.
І найголовніше: OAuth 2.0 дає ключ від чужого будинку, а OIDC — показує паспорт того, хто в нього заходить. Разом вони утворюють непорушний стандарт ідентифікації сучасного вебу.
Безпека на практиці: CORS, HTTPS та захист від атак
Повна конфігурація безпеки Minimal API: CORS, HTTPS Redirection, HSTS, CSRF-захист, Rate Limiting, заголовки безпеки, зберігання секретів та production чеклист.
OIDC, OAuth 2.0 та Keycloak в ASP.NET Core
Глибоке занурення в OpenID Connect та OAuth 2.0: навіщо вони потрібні, як працює Authorization Code Flow з PKCE, інтеграція з Keycloak як Identity Provider, JWT-валідація для API та Machine-to-Machine комунікація.