atpv

Навчальні матеріали з автоматизації технологічних процесів та виробництв, розроблені спільнотою

<- До підрозділу Коментувати

JSON Web Tokens : теоретична частина

У даному розділі використані матеріали JWT Handbook

1. Теоретичні відомості

Веб-токен JSON (JWT) — це відкритий стандарт (RFC 7519), який означує компактний і самодостатній спосіб безпечної передачі інформації між сторонами в форматі об’єкту JSON. Цю інформацію можна перевірити та довіряти їй, оскільки вона має цифровий підпис. JWT можна підписати за допомогою секрету (з алгоритмом HMAC) або пари відкритих/приватних ключів за допомогою RSA або ECDSA.

Хоча JWT можна повністю зашифрувати, щоб також забезпечити секретність між сторонами, ми зосередимося на підписаних токенах. Підписані токени (Signed tokens) можна перевірити на цілісність тверджень (claims), що містяться в ньому, тоді як зашифровані токени (encrypted tokens) приховують ці твердження від інших сторін. Коли токени підписуються за допомогою пар відкритих/приватних ключів, підпис засвідчує, що лише сторона, яка володіє закритим ключем, є тією, яка його підписала.

Примітка: слова маркер та токен в даному розділі вважаються синонімами.

Коли слід використовувати веб-токени JSON?

Ось кілька сценаріїв, коли веб-маркери JSON корисні:

  • Авторизація: це найпоширеніший сценарій використання JWT. Після входу користувача кожен наступний запит включатиме JWT, що дозволить користувачеві отримати доступ до маршрутів, послуг і ресурсів, які дозволені за допомогою цього маркера. Єдиний вхід (Single Sign On) — це функція, яка сьогодні широко використовує JWT через невеликі накладні витрати та можливість легкого використання в різних доменах.
  • Обмін інформацією: веб-токени JSON модна також використовувати для безпечного обміну інформації між сторонами. Оскільки JWT можна підписувати, наприклад, за допомогою пари відкритих/приватних ключів, ви можете бути впевнені, що відправники є тими, за кого себе видають. Крім того, оскільки підпис обчислюється за допомогою заголовка та корисного навантаження, ви також можете перевірити, чи вміст не було змінено.

Структура JSON веб-токена

У своїй компактній формі веб-токени JSON складаються з трьох частин, розділених крапками (.):

  • Header (Заголовок)
  • Payload (Корисне навантаження)
  • Signature (Підпис)

Таким чином, JWT зазвичай виглядає так:

xxxxx.yyyyy.zzzzz

Наприклад:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Заголовок зазвичай складається з двох частин: типу токена, яким є JWT, і використовуваного алгоритму підпису, наприклад HMAC SHA256 або RSA. Наприклад:

{
  "alg": "HS256",
  "typ": "JWT"
}

JWS допускає особливі випадки використання, які змушують заголовок містити більше полів. Наприклад, для алгоритмів підписання відкритим ключем можна вставити додаткове твердження - URL-адресу відкритого ключа .

Потім цей JSON кодується в форматі Base64Url, яка формує першу частину JWT.

Payload

Друга частина токена — це корисне навантаження (payload), яке містить твердження. Твердження (Claims) – це заяви про сутність (як правило, користувача) і додаткові дані. Існує три типи тверджень: зареєстровані, публічні та приватні твердження.

Зареєстровані твердження - це набір попередньо означених тверджень, які не є обов’язковими. Однак вони рекомендовані, щоб забезпечити набір корисних, інтероперабельних тверджень. Ось їх перелік:

  • iss (issuer, емітент) рядок або URI з урахуванням регістру, який унікально ідентифікує сторону, яка видала JWT. Його інтерпретація залежить від застосунку (немає центрального органу управління емітентами).

  • sub (subject, тема), - рядок або URI з урахуванням регістру, який унікально ідентифікує сторону, про яку цей JWT передає інформацію. Іншими словами, твердження, що містяться в цьому JWT, є заявами щодо цієї сторони. Специфікація JWT означує, що ця заява має бути унікальною в контексті емітента або, у випадках, коли це неможливо, глобально унікальною. Обробка цього твердження залежить від конкретного застосунку.

  • aud (audience, аудиторія) - один рядок з урахуванням регістру, або URI, або масив таких значень, які однозначно ідентифікують призначених одержувачів цього JWT. Іншими словами, коли це твердження присутня, сторона, яка читає дані в цьому JWT, повинна знайти себе в твердженні aud або ігнорувати дані, що містяться в JWT. Як і у випадку з першою та підпунктами формули, ця формула стосується конкретного застосунку.

  • exp (expiration, термін дії) - число, що представляє певну дату й час у форматі «секунди з епохи», як визначено POSIX6. Це твердження встановлює точний момент, з якого цей JWT вважається недійсним. Деякі реалізації можуть допускати певний перекіс між тактами (вважаючи цей JWT дійсним протягом кількох хвилин після закінчення терміну дії).

  • nbf (not before, від не раніше) - протилежне твердження exp. Число, що представляє певну дату й час у форматі «секунди з епохи», як визначено POSIX7. Це твердження встановлює точний момент, з якого цей JWT вважається дійсним. Поточний час і дата повинні відповідати або бути пізнішими за цю дату і час. Деякі реалізації можуть допускати певний перекіс.

  • iat (from issued at, виданий від) - число, що представляє конкретну дату й час (у тому самому форматі, що й exp і nbf), коли було видано цей JWT.

  • jti (from JWT ID, виданий ID) - рядок, що представляє унікальний ідентифікатор для цього JWT. Це твердження може бути використаною, щоб відрізнити JWT від іншого подібного вмісту (наприклад, для запобігання повторам). Саме реалізація гарантує унікальність.

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

Публічні твердження - можуть бути означені за бажанням користувачами JWT. Але щоб уникнути зіткнень, їх слід визначити в IANA JSON Web Token Registry або означити як URI, який містить простір імен, стійкий до зіткнень.

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

Прикладом корисного навантаження може бути:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

Payload так само як і Header кодується за допомогою Base64Url для формування другої частини веб-токена JSON.

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

Signature

Щоб створити третю частину - підпис, потрібно взяти закодовані заголовок (Header) і корисну інформацію (Payload), секрет, алгоритм що вказаний у заголовку, і підписати це. Наприклад, якщо ви хочете використовувати алгоритм HMAC SHA256, підпис буде створено таким чином:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

Підпис використовується для перевірки того, що повідомлення не було змінено на шляху, і, у випадку маркерів, підписаних закритим ключем, він також може підтвердити, що відправник JWT є тим, за кого він себе називає.

Все разом

Результатом є три рядки Base64-URL, розділені крапками, які можна легко передати в середовищах HTML і HTTP, але при цьому є більш компактними порівняно зі стандартами на основі XML, такими як SAML. Нижче показано JWT, який має попередній заголовок і корисне навантаження, закодовані та підписані секретом.

Encoded JWT

рис.1. Вигляд JWT

Якщо ви хочете погратися з JWT і застосувати ці концепції на практиці, ви можете використовувати jwt.io Debugger для декодування, перевірки та створення JWT.

JWT.io Debugger

рис.2. Зовнішній вигляд jwt.io Debugger

Як працюють веб-токени JSON?

Під час автентифікації, коли користувач успішно ввійде, використовуючи свої облікові дані, буде повернено веб-токен JSON. Оскільки токени є обліковими даними, потрібно бути дуже обережним, щоб запобігти проблемам безпеки. Загалом, токени не повинні зберігатися довше, ніж потрібно. Також не варто зберігати конфіденційні дані сеансу в пам’яті браузера через відсутність безпеки, прочитайте цю статтю.

Щоразу, коли користувач хоче отримати доступ до захищеного маршруту або ресурсу, агент користувача повинен надіслати JWT, як правило, у заголовку Authorization за допомогою схеми Bearer. Вміст заголовка має виглядати так:

Authorization: Bearer <token>

У деяких випадках це може бути механізм авторизації без стану. Захищені маршрути сервера перевірятимуть дійсний JWT у заголовку Authorization, і якщо він присутній, користувачеві буде дозволено доступ до захищених ресурсів. Якщо JWT містить необхідні дані, потреба запитувати базу даних для певних операцій може бути зменшена, хоча це не завжди так.

Зауважте, що якщо ви надсилаєте маркери JWT через заголовки HTTP, ви повинні намагатися запобігти тому, щоб вони ставали занадто великими. Деякі сервери не приймають заголовки розміром більше 8 КБ. Якщо ви намагаєтеся вставити забагато інформації в маркер JWT, наприклад, включивши всі дозволи користувача, вам може знадобитися альтернативне рішення, наприклад Auth0 Fine-Grained Authorization.

Якщо маркер надіслано в заголовку Authorization, перехресне використання ресурсів (CORS) не буде проблемою, оскільки він не використовує файли cookie.

На наступній діаграмі показано, як JWT отримується та використовується для доступу до API або ресурсів:

How does a JSON Web Token work

рис.3. Приклад отримання маркеру доступу.

  1. Програма або клієнт запитує авторизацію на сервері авторизації. Це виконується за допомогою одного з різних потоків авторизації. Наприклад, типова сумісна веб-програма OpenID Connect проходитиме через кінцеву точку /oauth/authorize за допомогою потоку коду авторизації.
  2. Коли авторизацію надано, сервер авторизації повертає програмі маркер доступу.
  3. Програма використовує маркер доступу для доступу до захищеного ресурсу (наприклад, API).

Зауважте, що з підписаними маркерами вся інформація, що міститься в маркері, доступна користувачам або іншим сторонам, навіть якщо вони не можуть її змінити. Це означає, що ви не повинні розміщувати секретну інформацію в маркері.

Порівнянн веб-токенів JSON з альтернативними

Давайте поговоримо про переваги веб-токенів JSON (JWT) порівняно з простими веб-токенами (SWT) і маркерами мови розмітки безпеки (SAML).

Оскільки JSON є менш детальним, ніж XML, коли він закодований, його розмір також менший, що робить JWT більш компактним, ніж SAML. Це робить JWT хорошим вибором для передачі в середовищах HTML і HTTP.

З точки зору безпеки SWT може бути лише симетрично підписаний спільним секретом за допомогою алгоритму HMAC. Проте маркери JWT і SAML можуть використовувати для підпису пару відкритих/приватних ключів у формі сертифіката X.509. Підписати XML за допомогою цифрового підпису XML без введення незрозумілих прогалин у безпеці дуже складно порівняно з простотою підпису JSON.

Парсери JSON поширені в більшості мов програмування, оскільки вони відображаються безпосередньо на об’єкти. І навпаки, XML не має природного відображення документа в об’єкт. Це полегшує роботу з JWT, ніж із твердженнями SAML.

Що стосується використання, JWT використовується в масштабі Інтернету. Це підкреслює легкість клієнтської обробки веб-токена JSON на багатьох платформах, особливо мобільних.

Comparing the length of an encoded JWT and an encoded SAML

рис.4. Порівняння довжини закодованого JWT і закодованого SAML

Якщо ви хочете дізнатися більше про веб-токени JSON і навіть почати використовувати їх для автентифікації у власних програмах, перейдіть на цільову сторінку веб-токенів JSON в Auth0.

2. Практичне застосування та вразливості

Цей розділ дасть вам уявлення про складність (або простоту) звичайних рішень на основі JWT, які сьогодні використовуються в галузі. Для вашої зручності весь код доступний у загальнодоступних репозиторіях. Майте на увазі, що наведені нижче демонстрації не призначені для використання у виробництві. Тестові випадки, ведення журналів і найкращі методи безпеки є важливими для готового до виробництва коду. Ці зразки призначені лише для освітніх цілей, тому залишаються простими та по суті.

Сеанси без стану (клієнтська сторона)

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

JWT, завдяки JWS і JWE, можуть надавати різні типи підписів і шифрування. Підписи корисні для перевірки даних на предмет підробки. Шифрування корисно для захисту даних від читання третіми сторонами.

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

Поширеним прикладом твердження, яке зазвичай можуть безпечно прочитати третьою стороною, є sub (тема). Це твердження зазвичай ідентифікує одну зі сторін (наприклад ідентифікатори користувачів або електронні адреси). Не обов’язково, щоб це твердження було унікальним. Іншими словами, для однозначної ідентифікації користувача можуть знадобитися інші додаткові твердження. Це залишається на вирішення реалізації.

Твердження, яке не можна належним чином залишати відкритим, може бути items, що представляє кошик користувача. Цей кошик може бути заповнений товарами, які користувач збирається придбати, і тому вони пов’язані з ним або його сеансом. Третя сторона (сценарій на стороні клієнта) може отримати ці елементи, якщо вони зберігаються в незашифрованому JWT, що може викликати проблеми з конфіденційністю.

image-20230513093922178

Рис 5: Підписані дані на стороні клієнта

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

image-20230513093949383

Рис. 6: Видалення підпису

Підробка міжсайтового запиту (CSRF)

Атаки підробки міжсайтових запитів намагаються виконувати запити проти сайтів, на яких користувач увійшов, обманом змушуючи браузер користувача надіслати запит з іншого сайту. Щоб досягти цього, спеціально створений сайт (або елемент) повинен містити URL-адресу цілі. Типовим прикладом є тег <img>, вбудований у шкідливу сторінку з src, що вказує на ціль атаки. Наприклад:

<!-- Це вбудовано в сайт іншого домену -->
<img src="http://target.site.com/add-user?user=name&grant=admin">

Наведений вище тег <img> надсилатиме запит до target.site.com кожного разу, коли завантажуватиметься сторінка, яка його містить. Якщо користувач раніше входив у систему на target.site.com і сайт використовував файл cookie, щоб підтримувати сеанс активним, цей файл cookie також буде надіслано. Якщо цільовий сайт не реалізує жодних методів пом’якшення CSRF, запит буде оброблено як дійсний запит від імені користувача. JWT, як і будь-які інші клієнтські дані, можна зберігати як файли cookie.

image-20230513094005600

Рис. 7: Підробка міжсайтового запиту (Cross-Site Request Forgery)

Короткочасні JWT можуть допомогти в цьому випадку. Загальні методи пом’якшення CSRF включають спеціальні заголовки, які додаються до запитів лише тоді, коли вони виконуються з правильного джерела, сеансових файлів cookie та маркерів запиту. Якщо JWT (і дані сеансу) не зберігаються як файли cookie, атаки CSRF неможливі. Однак міжсайтові сценарні атаки все ще можливі.

Cross-Site Scripting (XSS)

Атаки міжсайтового сценарію (XSS) намагаються впровадити JavaScript у надійні сайти. Введений JavaScript може потім викрасти маркери з файлів cookie та локального сховища. Якщо маркер доступу витік до закінчення терміну дії, зловмисник може використати його для доступу до захищених ресурсів. Поширені атаки XSS зазвичай спричинені неправильною перевіркою даних, що передаються на сервер (подібно до атак SQL-ін’єкцій).

Приклад XSS-атаки може бути пов’язаний із розділом коментарів на публічному сайті. Щоразу, коли користувач додає коментар, він зберігається серверною частиною та відображається користувачам, які завантажують розділ коментарів. Якщо серверна частина не очищає коментарі, зловмисник може написати коментар таким чином, що він може бути інтерпретований браузером як тег <script>. Отже, зловмисник може вставити довільний код JavaScript і виконати його в браузері кожного користувача, таким чином викравши облікові дані, що зберігаються як файли cookie та в локальному сховищі.

image-20230513094019358

Рис.8. Постійний міжсайтовий сценарій

image-20230513094033958

Рис.9: Рефлексивний міжсайтовий сценарій

Методи пом’якшення покладаються на належну перевірку всіх даних, що передаються до серверної частини. Зокрема, будь-які дані, отримані від клієнтів, завжди повинні бути оброблені. Якщо використовуються файли cookie, можна захистити їх від доступу з боку JavaScript, встановивши прапорець HttpOnly. Прапор HttpOnly, хоч і корисний, не захистить файл cookie від атак CSRF.

Чи корисні сеанси на стороні клієнта?

У будь-якого підходу є плюси та мінуси, і сеанси на стороні клієнта не є винятком. Для деяких програм можуть знадобитися великі сеанси. Надсилання цього стану туди й назад для кожного запиту (або групи запитів) може легко подолати переваги зменшення “балакучості” у серверній частині. Необхідний певний баланс між даними на стороні клієнта та пошуком у базі даних у серверній частині. Це залежить від моделі даних вашої програми. Деякі програми погано відображаються на клієнтських сесіях. Інші можуть повністю залежати від даних клієнта. Останнє слово в цьому питанні за вами! Виконайте контрольні тести, вивчіть переваги збереження певного стану на стороні клієнта:

  • JWT занадто великі?
  • Чи впливає це на пропускну здатність?
  • Чи ця додаткова пропускна здатність скасовує зменшену затримку у серверній частині?
  • Чи можна невеликі запити об’єднати в один більший запит?
  • Чи вимагають ці запити все ще великі пошуки в базі даних?

Відповіді на ці запитання допоможуть вам вибрати правильний підхід.

Системи об’єднаної ідентифікації

Системи об’єднаної ідентифікації (Federated identity systems) дозволяють різним, можливо непов’язаним сторонам, спільно використовувати служби автентифікації та авторизації з іншими сторонами. Іншими словами, ідентичність користувача централізована. Існує кілька рішень для федеративного керування ідентифікацією: SAML8 і OpenID Connect є двома найпоширенішими. Деякі компанії надають спеціалізовані продукти, які централізують автентифікацію та авторизацію. Вони можуть використовувати один із згаданих вище стандартів або використовувати щось зовсім інше. Деякі з цих компаній використовують JWT для цієї мети.

Використання JWT для централізованої автентифікації та авторизації залежить від компанії, але основний процес авторизації має вигляд як на рис.10:

image-20230513094107155

Рис.10: Загальний федеративний потік ідентифікації

  1. Користувач намагається отримати доступ до ресурсу, який контролюється сервером.
  2. Користувач не має належних облікових даних для доступу до ресурсу, тому сервер перенаправляє користувача на сервер авторизації. Сервер авторизації налаштовано, щоб дозволити користувачам входити в систему за допомогою облікових даних, якими керує постачальник ідентифікаційних даних (identity provider).
  3. Сервер авторизації перенаправляє користувача на екран входу постачальника ідентифікаційних даних.

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

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

Усі дані, що передаються від сервера до сервера, проходять через користувача, будучи вбудованими в запити перенаправлення (зазвичай як частина URL-адреси). Це робить транспортну безпеку (TLS) і безпеку даних надзвичайно важливими.

Облікові дані, які сервер авторизації повертає користувачеві, можуть бути закодовані як JWT. Якщо сервер авторизації дозволяє вхід через постачальника ідентифікаційної інформації (як у випадку в цьому прикладі), можна сказати, що сервер авторизації надає уніфікований інтерфейс і уніфіковані дані (JWT) для користувача.

У нашому прикладі далі в цьому розділі ми будемо використовувати Auth0 як сервер авторизації та оброблятимемо входи через Twitter, Facebook і звичайну базу даних користувачів.

Маркери доступу та оновлення

Маркери доступу та оновлення — це два типи маркерів, які ви часто побачите під час аналізу різних рішень федеративної ідентифікації. Ми коротко пояснимо, що це таке та як вони допомагають у контексті автентифікації та авторизації.

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

Маркери (токени) доступу – це маркери, які надають тим, хто їх має, доступ до захищених ресурсів. Ці токени зазвичай недовговічні та можуть мати вбудовану дату закінчення терміну дії. Вони також можуть містити додаткову інформацію або бути пов’язаною з нею (наприклад, маркер доступу може містити IP-адресу, з якої дозволені запити). Ці додаткові дані визначаються реалізацією.

З іншого боку, Маркери оновлення дозволяють клієнтам запитувати нові маркери доступу. Наприклад, після закінчення терміну дії маркера доступу клієнт може виконати запит нового маркера доступу до сервера авторизації. Щоб цей запит було задоволено, потрібен маркер оновлення. На відміну від маркерів доступу, маркери оновлення зазвичай довгоживучі.

image-20230513094129535

Рис.11. Оновлення та доступ до маркерів

Ключовий аспект поділу між маркерами доступу та оновлення полягає в можливості полегшення перевірки маркерів доступу. Маркер доступу, який містить підпис (наприклад, підписаний JWT), може бути перевірений сервером ресурсів самостійно. Для цього не потрібно звертатися до сервера авторизації.

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

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

Примітка: концепції маркера доступу та маркера оновлення були представлені в OAuth2. OAuth 1.0 і 1.0a використовують слово токен по-різному.

JWTs та OAuth2

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

JWT також можна використовувати для маркерів оновлення. Однак немає причин використовувати їх для цієї мети. Оскільки для маркерів оновлення потрібен доступ до сервера авторизації, у більшості випадків буде достатньо простого UUID, оскільки немає потреби, щоб маркер переносив корисне навантаження (проте він може бути підписаний).

JWTs і OpenID Connect

OpenID Connect — це спроба стандартизації, щоб об’єднати типові випадки використання OAuth2 під загальну, чітко визначену специфікацію. Оскільки багато деталей, що стоять за OAuth2, залишено на вибір розробників, OpenID Connect намагається надати правильні визначення для відсутніх частин. Зокрема, OpenID Connect визначає API і формат даних для виконання потоків авторизації OAuth2. Крім того, він забезпечує рівень автентифікації, побудований поверх цього потоку. Для деяких його частин обрано формат даних JSON Web Token. Зокрема, ідентифікаційний токен — це особливий тип токена, який містить інформацію про автентифікованого користувача.

OpenID Connect Flows та JWTs

OpenID Connect визначає кілька потоків, які повертають дані різними способами. Деякі з цих даних можуть бути у форматі JWT.

  • Потік авторизації: клієнт запитує код авторизації до кінцевої точки авторизації (/authorize). Цей код можна використовувати проти кінцевої точки маркера (/token), щоб запитати маркер ідентифікатора (у форматі JWT), маркер доступу або маркер оновлення.
  • Неявний потік: клієнт запитує маркери безпосередньо від кінцевої точки авторизації (/authorize). Токени вказуються в запиті. Якщо запитується маркер ідентифікатора, він повертається у форматі JWT.
  • Гібридний потік: клієнт запитує як код авторизації, так і певні токени від кінцевої точки авторизації (/authorize). Якщо запитується маркер ідентифікатора, він повертається у форматі JWT. Якщо ідентифікаційний маркер не запитується на цьому кроці, пізніше його можна запросити безпосередньо з кінцевої точки маркера (/token).

Приклад

У цьому прикладі ми будемо використовувати Auth0 як сервер авторизації. Auth0 дозволяє динамічно встановлювати різних постачальників посвідчень. Іншими словами, щоразу, коли користувач намагається ввійти, зміни, внесені на сервер авторизації, можуть дозволити користувачам увійти за допомогою інших постачальників ідентифікаційних даних (таких як Twitter, Facebook тощо). Після розгортання програм не потрібно прив’язувати до певних постачальників. Тому наш приклад може бути досить простим. Ми налаштували екран входу Auth0 за допомогою бібліотеки Auth0.js на всіх наших зразках серверів. Після входу на один сервер користувач також матиме доступ до інших серверів (навіть якщо вони не з’єднані між собою).

image-20230513094148355

Рис.12: Auth0 as Authorization Servers

Налаштування бібліотеки Auth0 можна виконати наступним чином. Ми використаємо той самий приклад, що й для прикладу сеансів без стану:

const auth0 = new window.auth0.WebAuth({ 
    domain: domain, 
    clientID: clientId,
    audience: 'app1.com/protected', 
    scope: 'openid profile purchase', 
    responseType: 'id_token token',
    redirectUri: 'http://app1.com:3000/auth/', 
    responseMode: 'form_post'
});
// (...)
$('#login-button').on(
    'click', 
    function(event) { auth0.authorize({prompt: 'none' });}
);

Зверніть увагу на використання параметра підказки: ‘none’ для авторизаційного виклику. Authorizecall перенаправляє користувача на сервер авторизації. За допомогою параметра none, якщо користувач уже авторизував програму на використання його або її облікових даних для доступу до захищеного ресурсу, сервер авторизації просто перенаправить назад до програми. Користувач виглядає так, ніби він уже ввійшов у програму.

У нашому прикладі є дві програми: app1.com і app2.com. Коли користувач авторизує обидві програми (що відбувається лише один раз: під час першого входу користувача), будь-які наступні входи в будь-яку з обох програм також дозволять іншій програмі ввійти без відображення екранів входу.

Щоб перевірити це, перегляньте файл README для прикладу, який знаходиться в каталозі samples/single-sign-on-federated-identity, щоб налаштувати обидві програми та запустити їх. Коли обидва запущені, перейдіть на app1.com:300016 і app2.com:300117 і увійдіть. Потім вийдіть з обох програм. Тепер спробуйте увійти в один із них. Потім поверніться до іншого та увійдіть. Ви помітите, що екран входу буде відсутній в обох програмах. Сервер авторизації запам’ятовує попередні входи та може видавати нові маркери доступу за запитом будь-якої з цих програм. Таким чином, поки користувач має сеанс сервера авторизації, він або вона вже ввійшли в обидві програми.

Впровадження методів пом’якшення CSRF залишається для читача як вправа.

Посилання

https://jwt.io/

http://auth0.com/learn/json-web-tokens

https://github.com/sunilchauhan1/jwtExamples/blob/master/jwt-handbook-v0_14_1.pdf

Автори

Теоретичне заняття адаптував Олександр Пупена.

Feedback

Якщо Ви хочете залишити коментар у Вас є наступні варіанти:

Про проект і можливість допомогти проекту написано тут