Чому в OAuth2 існує потік «Код авторизації», коли потік «Неявно» працює так добре?


264

З потоком "Неявне" клієнт (швидше за все, браузер) отримає маркер доступу після того, як Власник ресурсу (тобто користувач) надав доступ.

Однак з потоком "Код авторизації" клієнт (зазвичай веб-сервер) отримує код авторизації лише після того, як Власник ресурсу (тобто користувач) надав доступ. За допомогою цього коду авторизації клієнт здійснює ще один виклик API, що передає client_id та client_secret, разом з кодом авторизації для отримання маркера доступу. Тут все добре описано .

Обидва потоки мають точно такий же результат: маркер доступу. Однак потік "неявного" набагато простіший.

Питання: Навіщо турбуватися з потоком "Код авторизації", коли шви потоку "Неявні" мають бути в порядку? Чому б також не використовувати "Неявно" для веб-сервера?

Це більше роботи як для провайдера, так і для клієнта.



1
Дякую, прочитайте вже. Однак не відповідає на питання.
Арон Вуст

1
Насправді добре питання і на нього рідко відповідають :) Дивіться нижче.
Ніколя Гарньє

1
@AronWoost Я думаю, що ви неправильно розумієте веб-додаток та додаток для браузера
onmyway133,

@entropy Це було моє питання; чому б не використовувати потік браузера і для сервера.
Арон Вуст

Відповіді:


293

tl; dr: Це все з міркувань безпеки.

OAuth 2.0 хотів відповідати цим двом критеріям:

  1. Ви хочете дозволити розробникам використовувати URI для перенаправлення без HTTPS, оскільки не всі розробники мають сервер із підтримкою SSL, і якщо вони роблять, це не завжди правильно налаштовано (непідписані самостійно, надійні сертифікати SSL, синхронізований серверний годинник ...).
  2. Ви не хочете, щоб хакери могли вкрасти доступ / оновити маркери, перехоплюючи запити.

Деталі нижче:

Неявний потік можливий лише в середовищі браузера з міркувань безпеки:

У неявному потоці маркер доступу передається безпосередньо як хеш-фрагмент (а не як параметр URL). Важлива річ щодо хеш-фрагмента - це те, що після переходу посилання, що містить хеш-фрагмент, лише браузер знає про хеш-фрагмент. Браузери передадуть хеш-фрагмент безпосередньо до цільової веб-сторінки (URI переспрямування / веб-сторінки клієнта). Фрагмент хешу має такі властивості:

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

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

Неявний потік також має проблеми із безпекою, що вимагає додаткової логіки для вирішення / уникання, наприклад:

  • Зловмисник може отримати маркер доступу від користувача на іншому веб-сайті / додатку (скажімо, якщо він є власником іншого веб-сайту / програми), увімкніть маркер на своєму веб-сайті, а потім передайте його як парам-параметр URL на своєму веб-сайті. тому видає себе за користувача на вашому веб-сайті. Щоб уникнути цього, вам потрібно перевірити ідентифікатор клієнта, пов’язаний з маркером доступу (наприклад, для Google ви можете використовувати кінцеву точку tokeninfo), щоб переконатися, що маркер видано з вашим власним ідентифікатором клієнта (тобто, власним додатком) або перевірити підпис якщо ви використовуєте IDToken (але для цього потрібен секрет вашого клієнта).
  • Якщо запит на отримання автентичності не походить з вашого власного ресурсу (звані атаки виправлення сеансу), щоб уникнути цього, вам потрібно буде генерувати випадковий хеш із вашого веб-сайту, зберегти його у файлі cookie та передати цей самий хеш у параметр URL-адреси стану запит на аутентифікацію, коли користувач повертається, ви перевіряєте параметр стану з файлом cookie, і він повинен відповідати.

У потоці коду авторизації неможливо передати маркер доступу безпосередньо в параметрі URL, оскільки параметри URL є частиною HTTP-запиту, тому будь-який посередник / маршрутизатор, через який проходитиме ваш запит (може бути сотнями), зможе читайте маркер доступу, якщо ви не використовуєте зашифроване з'єднання (HTTPS), що дозволяє називати атаки "людина-в-середині".

Передача маркера доступу безпосередньо в парам-адресі URL теоретично може бути можливим, але автентичний сервер повинен переконатися, що URI перенаправлення використовує HTTPS з TLS-шифруванням та "довіреним" SSL-сертифікатом (як правило, з сертифікаційного органу, який не є безкоштовним) щоб бути впевненим, що цільовий сервер є законним і що HTTP-запит повністю зашифрований. Якщо всі розробники придбають сертифікат SSL і правильно налаштувати SSL для свого домену, це буде величезним болем і дуже сповільнить прийняття. Ось чому посередницький "код авторизації" для одноразового використання надається лише тим, що законний приймач зможе обмінятися (тому що вам потрібен секрет клієнта) і що код буде марний потенційним хакерам, що перехоплюють запити за незашифрованими транзакціями (тому що вони не '

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


12
@AndyDufresne Ці два запити повинні бути виконані через HTTPS (обов'язковий), оскільки вони є запитами до сервера OAuth, який повинен підтримувати лише HTTPS. Це лише сервер клієнта / запитувача, який не повинен підтримувати HTTPS, тому тільки Auth CodeHTTP надсилається через HTTP. Але Auth Codeце марно без ідентифікатора клієнта / секрету. В основному суть потоку коду OAuth полягає в тому, що тягар наявності сервера, що підтримує SSL, лежить на постачальнику OAuth (Google / Facebook тощо), а не на користувачах API (ви, я).
Ніколя Гарньє

5
Гаразд, тепер я слідую за тим, що код автентичності може бути переданий через звичайний HTTP і є ризик отримати обнюх. Зробивши код одноразового використання та прийнявши секрет клієнта для обміну ним на маркер доступу, сервер авторизації міг запобігти атаці "Людина в середині". Але це також не стосується маркера доступу? Оскільки користувач API може знаходитись на звичайному HTTP, чи не буде ризику хакер-нюхати токеном доступу? PS - Я вдячний вашим зусиллям щодо пояснення концепції навіть після того, як минув час, коли ця тема була активною. Дякую !
Енді Дуфресне

8
no pb :) Запити до API - це, коли маркер доступу надсилається по дроту (для авторизації запиту) - також виконується через HTTPS обов'язково. Теоретично клієнт ніколи не повинен надсилати маркер доступу по протоколу звичайного HTTP.
Ніколя Гарньє

5
Токен доступу на цьому кроці є частиною відповіді на запит HTTPS від Клієнта до сервера ресурсів. Ця відповідь все ще зашифрована.
Ніколя Гарньє

13
В основному запити, які ініціюються від клієнта до ресурсного сервера, виконуються через HTTPS (оскільки сервер власника ресурсу повинен підтримувати підтримку HTTPS). Це лише запити, ініційовані з іншого місця до клієнта, які можуть бути виконані через HTTP (оскільки клієнтський сервер може не підтримувати HTTPS). Наприклад, переспрямування, яке відбувається під час потоку аутентифікації після надання користувачем авторизації на сторінці gant, є переспрямуванням, ініційованим з браузера на клієнтський сервер, і може здійснюватися на HTTP.
Ніколя Гарньє

8

Неявна Flow робить весь потік досить легко, але і менш безпечною .
Оскільки клієнтська програма, яка, як правило, працює в браузері JavaScript, менш довіряє, токени оновлення для довготривалого доступу не повертаються.
Ви повинні використовувати цей потік для додатків, які потребують тимчасового доступу (до декількох годин) до даних користувача.
Повернення маркера доступу до клієнтів JavaScript також означає, що ваш додаток на базі браузера повинен бути особливо обережним - подумайте про XSS Attacks, які могли би витікати маркер доступу до інших систем.

https://labs.hybris.com/2012/06/05/oauth2-the-implicit-flow-aka-as-the-client-side-flow


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

Також мова йде не лише про міжсайтовий сценарій. Будь-яка бібліотека JavaScript, що працює на вашому веб-сайті, може спробувати вкрасти маркер доступу (наприклад, сторонні бібліотеки CDN або бібліотеки з відкритим кодом, які використовує ваша рамка JavaScript).
Марсель

2
XSS не є великою проблемою зараз, коли у нас є заголовки політики безпеки вмісту та хеші цілісності субресурсів (SRI).
Сергій Пономарьов

4

З специфікації OAuth :

4.2. Неявна грант

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

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

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

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

Отже, що ми можемо врахувати:

  1. Це для публічного OAuth, тобто коли клієнту не потрібно було реєструватися та не має власної клієнтської таємниці. Але те, що автентичний сервер перевіряє URL-адресу переадресації, і цього насправді достатньо для безпеки.

  2. Маркер доступу виникає в адресному рядку веб-переглядача, щоб користувач міг скопіювати URL-адресу та надіслати комусь іншому, і він також стане зареєстрованим як користувач, тобто це щось на зразок фіксації сесії. Але браузер робить додатковий переспрямування із заміною історії, щоб видалити хеш-фрагмент з URL. Також хакеру можна вкрасти маркер доступу, обнюхуючи трафік HTTP, але це може бути легко захищено HTTPS. Деякі зловмисні розширення браузера можуть мати доступ до URL-адрес із адресного рядка, але це в кінцевому підсумку погана ситуація, наприклад, зламаний сервер HTTPS. Навіть потік коду Auth не може допомогти тут ефіру. Тож, що я бачу, це те, що передача маркера доступу через хеш-фрагмент URL-адреси абсолютно безпечна.

  3. Розділення ефемерного маркера доступу та оновлення токена марно під час використання HTTPS і, якщо чесно, не так корисно навіть у сирому HTTP. Але той факт, що клієнт через неявний потік не може отримати маркер оновлення, також є дурницею.

Таким чином, я думаю, що ми повинні запровадити новий потік грантів "безпечний неявний", який працює строго через https, дозволяє оновити маркер (або ми повинні взагалі позбутися від них) і є кращим, ніж потік грантів Auth Cose


3

Для нас, наші клієнти хотіли мати можливість автентифікувати наш додаток на своїх телефонах один раз, і не потрібно входити знову за тиждень. За допомогою потоку коду ви отримуєте маркер оновлення разом із маркером доступу. Неявний потік не дає вам ознаки оновлення. Маркер доступу має відносно короткий термін дії, але маркери оновлення можуть мати термін дії до 90 днів. Щоразу, коли маркер доступу закінчується, клієнтський і серверний код можуть використовувати цей маркер оновлення, щоб отримати новий маркер доступу плюс маркер оновлення, все поза кадром, без будь-якого втручання користувача. Маркер оновлення можна використовувати лише один раз. Ви не можете зробити це за допомогою неявного потоку. Якщо ви використовуєте Implicit Flow, і ваш користувач не взаємодіє з вашим додатком більше години, їм доведеться знову увійти, коли він повернеться. У нашому випадку це було неприйнятно,

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

Потік коду є приголомшливим, але це потребує більше роботи. У MS немає кутової бібліотеки, яка б обробляла її зараз, тому мені довелося написати її. Якщо ви зацікавлені, я можу вам у цьому допомогти.


2

Моя відповідь: ви не можете реалізувати неявний потік безпечно і просто з сервером веб-додатків.

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

Отже, маркер слід передати веб-додатку за допомогою URL-адреси для переадресації, правда?

Як пояснив @NicolasGarnier у своїй відповіді та коментарях, немає можливості передати маркер як фрагмент URL-адреси - він не дійде до сервера веб-додатків.

І передавання маркера як URL-адреси URL-адреси переадресації було б небезпечним навіть у HTTPS: якщо цільова сторінка (нехай це буде "сторінка привітання") містить ресурси (зображення, сценарії тощо), ці ресурси будуть отримані браузером через серію запитів HTTP (S) (кожен з яких має RefererHTTP-заголовок, що містить точну URL-адресу "сторінки привітання", включаючи параметри URL-адреси). Це спосіб лексеми може просочитися.

Тому, схоже, немає можливості передати маркер у URL-адресі переспрямування. Ось чому вам потрібен другий виклик (або з сервера аутентифікації до клієнта (але до якої URL-адреси?), Або від клієнта до сервера аутентифікації (другий виклик у потоці коду авторизації))

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.