Різниця між автентифікацією HTTP, ключами API та OAuth
https://nordicapis.com/the-difference-between-http-auth-api-keys-and-oauth/
Daniel Lindau, June 23, 2020
Розробляючи системи, які забезпечують безпечну автентифікацію та авторизацію для доступу до API, ви повинні розглянути, як ваші програми та користувачі мають автентифікуватися. У цій статті ми порівняємо три різні способи досягнення цієї мети: Ключі API, Базова автентифікація HTTP і OAuth. Ми також висвітлимо переваги та недоліки кожного методу.
API Keys
Використання ключів API — це спосіб автентифікації програми, яка отримує доступ до API, без посилання на фактичного користувача. Програма додає ключ до кожного запиту API, і API може використовувати ключ для ідентифікації програми та авторизації запиту. Потім ключ можна використовувати для виконання таких дій, як обмеження швидкості, статистика тощо.
Спосіб надсилання ключа відрізняється в різних API. Деякі API використовують параметри запиту, деякі використовують заголовок Authorize, деякі використовують параметри body тощо. Наприклад, Google Cloud приймає ключ API із таким параметром запиту:
curl -X POST https://language.googleapis.com/v1/documents:analyzeEntities?key=API_KEY
Cloudflare requires the API key to be sent in a custom header:
curl https://api.cloudflare.com/client/v4/zones/cd7d0123e301230df9514d \
-H "Content-Type:application/json" \
-H "X-Auth-Key:1234567893feefc5f0q5000bfo0c38d90bbeb" \
-H "X-Auth-Email:example@example.com"
Переваги
Клієнтам відносно легко використовувати ключі API. Незважаючи на те, що більшість провайдерів використовують різні методи, додати ключ до запиту API досить простий.
Недоліки
Ключ API ідентифікує лише програму, а не користувача програми. Часто буває важко зберегти ключ у секреті. Для міжсерверного зв’язку можна приховати ключ за допомогою TLS і обмежити доступ для використання лише у внутрішніх сценаріях. Однак, оскільки багато інших типів клієнтів будуть використовувати API, ключі, ймовірно, будуть витікати.
URL-адреси запитів можуть опинитися в журналах. Програми JavaScript мають більш-менш все у відкритому доступі. Мобільні програми легко декомпілювати тощо. Таким чином, розробники не повинні покладатися на ключі API лише для ідентифікації клієнта для статичних цілей. Крім того, ключі API також не стандартизовані, тобто кожен API має унікальну реалізацію.
HTTP Basic Auth
Базова автентифікація HTTP – це простий метод, який створює автентифікацію за допомогою імені користувача та пароля для запитів HTTP. Ця техніка використовує заголовок під назвою «Authorization» з представленням імені користувача та пароля в кодуванні base64. Залежно від варіанту використання базова автентифікація HTTP може автентифікувати користувача програми або саму програму.
Запит із використанням базової автентифікації для користувача daniel
з паролем password
виглядає так:
GET / HTTP/1.1
Host: example.com
Authorization: Basic ZGFuaWVsOnBhc3N3b3Jk
Під час використання базової автентифікації для API цей заголовок зазвичай надсилається в кожному запиті. Облікові дані стають більш-менш ключем API, коли використовуються як автентифікація для програми. Навіть якщо це ім’я користувача та пароль, це просто статичний рядок.
Теоретично пароль можна час від часу змінювати, але зазвичай це не так. Як і у випадку з ключами API, ці облікові дані можуть просочитися до третіх сторін. Звичайно, оскільки облікові дані надсилаються в заголовку, вони з меншою ймовірністю потраплять десь у журнал (лог), ніж за допомогою параметра запиту чи шляху, як це може зробити ключ API.
Зазвичай не рекомендується використовувати базову автентифікацію для автентифікації користувачів, оскільки надсилання облікових даних користувача для кожного запиту вважатиметься поганою практикою. Якщо базова автентифікація HTTP використовується лише для одного запиту, програмі все одно потрібно буде збирати облікові дані користувача. Користувач не може знати, для чого програма їх використовуватиме, і єдиний спосіб скасувати доступ – змінити пароль.
Переваги
HTTP Basic Auth – це стандартизований спосіб надсилання облікових даних. Заголовок завжди виглядає однаково, а компоненти легко реалізувати. Він простий у використанні і може бути гідною автентифікацією для програм у міжсерверних середовищах.
Недоліки
Коли користувач автентифікований, програмі потрібно отримати пароль. З точки зору користувача, неможливо знати, що програма робить з паролем. Додаток отримає повний доступ до облікового запису, і у користувача немає іншого способу скасувати доступ, крім зміни пароля. Паролі є довговічними маркерами, і якщо зловмисник заволодіє паролем, він, швидше за все, залишиться непоміченим. Коли використовується для автентифікації користувача, багатофакторна автентифікація неможлива.
Автентифікація на основі маркерів за допомогою OAuth 2.0
Архітектура на основі маркерів базується на тому, що всі служби отримують маркер як доказ того, що програмі дозволено викликати службу. Маркер видається третьою стороною, якій можна довіряти як програмою, так і службою. Наразі найпопулярнішим протоколом для отримання цих токенів є OAuth 2.0, визначений у RFC 6749.
OAuth означує механізми, за допомогою яких програма може запитувати у користувача доступ до служб від імені користувача та отримувати маркер як доказ того, що користувач погодився. Щоб продемонструвати, як працює OAuth, розглянемо наступний варіант використання.
Користувач Аліса має обліковий запис у службі, де вона може повідомляти поточну температуру в приміщенні свого будинку. Аліса також хоче надати сторонньому додатку доступ для читання даних про температуру, щоб мати можливість побудувати температуру на графіку та перехресно посилатися на дані з інших служб. Служба температури надає API з даними про температуру, тому програма стороннього розробника повинна мати досить простий доступ до даних. Але як зробити доступними для програми лише дані Аліси?
Збір облікових даних
Використовуючи базову автентифікацію, програма може збирати ім’я користувача та пароль Аліси для служби температури та використовувати їх для запиту даних служби. Потім служба температури може перевірити ім’я користувача та пароль і повернути запитувані дані.
Однак, як ми зазначали, у цьому підході є кілька проблем:
- Користувач повинен довіряти програмі облікові дані. Користувач не може дізнатися, для чого використовуються облікові дані.
- Єдиний спосіб для користувача скасувати доступ - це змінити пароль.
- Програма не автентифікована
- Обсяг доступу не контролюється. Користувач надав повний доступ до облікового запису.
- Не можна використовувати двофакторну аутентифікацію
Історично це спричинило потребу в службах для розробки «спеціальних паролів програм», тобто додаткових паролів для вашого облікового запису, які будуть використовуватися програмами. Це усуває необхідність повідомляти фактичний пароль, але зазвичай це означає надання повного доступу до облікового запису. З боку постачальника послуг ви можете побудувати логіку навколо поєднання паролів для програм із ключами API, що також може обмежити доступ, але це буде повністю індивідуальна реалізація.
Шлях OAuth
Давайте подивимося, як ми можемо вирішити цю проблему за допомогою стратегії OAuth 2.0. Щоб забезпечити кращу автентифікацію, служба температури повинна опублікувати сервер авторизації (AS), відповідальний за видачу токенів. Ця AS дозволяє стороннім програмам реєструватися та отримувати облікові дані для своєї програми, щоб мати можливість запитувати доступ від імені користувачів.
Щоб запитати доступ, програма може вказати браузер користувача на AS із такими параметрами, як:
https://as.temperatures.com/authorize?client_id=third_party_graphs&scope=read_temperatures&…
Цей запит переведе користувача до AS служби температури, де AS може автентифікувати Алісу будь-яким доступним методом. Оскільки це відбувається в браузері, можливе кілька факторів, і єдиний, хто бачить дані, це служба температури та власник облікового запису. Після автентифікації Аліси AS може запитати, чи можна дозволити доступ третій стороні. У цьому випадку було запропоновано діапазон read_temperature, тому AS може підказати конкретне запитання.
Коли Аліса приймає, клієнт може автентифікуватися. Маркер видається як доказ того, що Аліса прийняла делегований доступ, і надсилається назад сторонній програмі. Тепер стороння програма може викликати API за допомогою отриманого маркера. Маркер надсилається разом із запитом шляхом додавання його до заголовка авторизації з ключовим словом Bearer таким чином:
GET /temperature HTTP/1.1
Host api.temperatures.com
Authorization: Bearer
Отримавши запит, служба може перевірити токен і побачити, що Аліса дозволила програмі читати температурні списки з її облікового запису, і повернути дані програмі.
Перевірка маркера
Виданий маркер можна повернути двома способами: шляхом повернення посилання на дані маркера або безпосереднього повернення значення маркера. Для контрольного маркера служба повинна буде надіслати запит до AS, щоб перевірити маркер і повернути пов’язані з ним дані. Цей процес називається самоаналізом, і зразок відповіді виглядає так:
{
"active": true,
"sub": “alice”,
"client_id": "third_party_graphs",
"scope": "read_temperatures"
…
}
У цій відповіді ми бачимо, що користувач alice
надала додатку third_party_graphs
доступ до свого облікового запису з областю read_temperatures
. На основі цієї інформації служба може вирішити, дозволити чи відхилити запит. client_id
також можна використовувати для статистики та обмеження швидкості програми. Зверніть увагу, що ми отримали лише ім’я користувача облікового запису в прикладі, але оскільки AS виконує автентифікацію, вона також може повертати додаткові претензії у цій відповіді (наприклад, тип облікового запису, адреса, розмір взуття тощо). Претензії можуть бути будь-якими що може дозволити службі прийняти обґрунтоване рішення щодо авторизації.
Для повернення значення зазвичай використовується такий формат маркера, як JSON Web Token (JWT). Цей маркер можна підписати або зашифрувати, щоб служба могла перевірити маркер, просто використовуючи відкритий ключ довіреної AS. Тут ми бачимо чітку різницю:
- Аліса надала свої облікові дані лише надійному сайту.
- Можна використовувати багатофакторну автентифікацію.
- Аліса може скасувати доступ до програми, попросивши сайт температури відкликати її згоду, не змінюючи свій пароль
- Аліса може дозволити програмі третьої сторони отримувати доступ лише до певної інформації з її облікового запису.
- Претензії до користувача можуть бути доставлені в сервіс безпосередньо через запит. Додаткові пошуки не потрібні.
- Потік повністю стандартизований.
Висновки
Оскільки OAuth 2.0 було розроблено під час зростання ринку API, більшість варіантів використання ключів API та базової автентифікації вже розглянуто в рамках протоколу. Можна з упевненістю сказати, що він перевершує конкурентів за всіма показниками. Для невеликих, конкретних випадків використання може бути добре використовувати ключі API або базову автентифікацію, але будь-кому, хто створює системи, які планують розвиватися, слід звернути увагу на архітектуру на основі маркерів, таку як Neo Security Architecture.
У наведеному вище випадку використання я лише описав потік користувача, але OAuth, звичайно, вказує альтернативні потоки для отримання маркерів у міжсерверних середовищах. Ви можете прочитати більше про них у моїй попередній публікації, де розглядаються вісім типів потоків і повноважень OAuth.