Какой поток OAuth 2.0 лучше всего подходит для мобильного приложения

Я пытаюсь реализовать делегированную авторизацию в веб-API для мобильных приложений с использованием OAuth 2.0. Согласно спецификации, неявный поток предоставления не поддерживает токены обновления, что означает, что после предоставления токена доступа на определенный период времени пользователь должен снова предоставить разрешения приложению после истечения срока действия токена или его отзыва.

Я предполагаю, что это хороший сценарий для некоторого кода javascript, работающего в браузере, как указано в спецификации. Я пытаюсь свести к минимуму время, в течение которого пользователь должен предоставлять разрешения приложению для получения токена, поэтому похоже, что поток кода авторизации является хорошим вариантом, поскольку он поддерживает токены обновления.

Однако этот поток, похоже, сильно зависит от веб-браузера для выполнения перенаправлений. Мне интересно, подходит ли этот поток для мобильного приложения, если используется встроенный веб-браузер. Или мне следует использовать неявный поток?


person Pablo Cibraro    schedule 02.07.2013    source источник
comment
Возникает вопрос: является ли это высшим приоритетом, когда пользователю никогда не придется снова вводить пароль после первого входа в систему?   -  person leastprivilege    schedule 02.07.2013
comment
Да, это именно мое требование. Пользователь должен ввести пароль только один раз. Однако я не хочу настраивать токен с бесконечным временем жизни и хранить его в мобильном приложении, поскольку это противоречит возможности отзыва токена. (Если я не добавлю логику в мобильное приложение для обнаружения несанкционированного запроса, после этого я запрашиваю новый токен)   -  person Pablo Cibraro    schedule 02.07.2013
comment
Вы можете добавить токен с бесконечным сроком жизни и при этом отозвать его. И да, логика приложения должна уметь это определять. RFC 6750 определяет способ проверки, вызвана ли ошибка отозванным токеном.   -  person Pedro Felix    schedule 02.07.2013
comment
Пожалуйста, избегайте веб-представлений (если только вы не владеете полным стеком и не используете социальный вход), которые открывают возможность взлома паролей. Когда сторонний встроенный пользовательский агент запрашивает учетные данные, я удаляю приложение. Некоторые API-интерфейсы теперь даже запрещают такие интеграции, такие как этот dev.fitbit.com/docs/oauth2 Я дал еще один ответ, чтобы прояснить некоторые из этих концепций (stackoverflow.com/a/38582630/752167)   -  person Matt C    schedule 26.07.2016


Ответы (5)


Уточнение: мобильное приложение = собственное приложение

Как указано в других комментариях и нескольких источниках в Интернете, неявный вид кажется естественным подходом для мобильных приложений, однако лучшее решение не всегда однозначно (и на самом деле неявный не рекомендуется по причинам, обсуждаемым ниже).

Рекомендации по OAuth2 для нативных приложений

Какой бы подход вы ни выбрали (есть несколько компромиссов), вам следует обратить внимание на передовые практики, изложенные здесь для собственных приложений с использованием OAuth2: https://tools.ietf.org/html/rfc8252

Рассмотрим следующие варианты

Неявный

Должен ли я использовать неявный?

Цитата из раздела 8.2 https://tools.ietf.org/html/rfc8252#section-8.2

Поток неявной авторизации предоставления OAuth 2.0 (описанный в разделе 4.2 OAuth 2.0 [RFC6749]) обычно работает с практикой выполнения запроса авторизации в браузере и получения ответа авторизации через обмен данными между приложениями на основе URI.
Однако, поскольку неявный поток не может быть защищен PKCE [RFC7636] (который требуется в разделе 8.1), использование неявного потока с собственными приложениями НЕ РЕКОМЕНДУЕТСЯ.

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

Код авторизации

Если вы используете код авторизации, то одним из подходов будет прокси через ваш собственный компонент веб-сервера, который обогащает запросы токенов секретом клиента, чтобы избежать его хранения в распределенном приложении на устройствах.

Выдержка ниже из: https://dev.fitbit.com/docs/oauth2/

Поток предоставления кода авторизации рекомендуется для приложений, у которых есть веб-служба. Этот поток требует межсерверной связи с использованием секрета клиента приложения.

Примечание. Никогда не помещайте секрет клиента в распределенный код, например приложения, загруженные через магазин приложений, или клиентский JavaScript.

Приложения, у которых нет веб-службы, должны использовать поток неявного предоставления.

Заключение

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

Отличное чтение - здесь https://auth0.com/blog/oauth-2-best-practices-for-native-apps/

Другой - https://www.oauth.com/oauth2-servers/oauth-native-apps/, в котором говорится

В настоящее время передовой отраслевой практикой является использование потока авторизации, опуская секрет клиента, и использование внешнего пользовательского агента для завершения потока. Внешний пользовательский агент обычно является собственным браузером устройства (с отдельным доменом безопасности, отличным от собственного приложения), поэтому приложение не может получить доступ к хранилищу файлов cookie, а также проверить или изменить содержимое страницы внутри браузера.

Рассмотрение PKCE

Вам также следует рассмотреть PKCE, описанный здесь https://www.oauth.com/oauth2-servers/pkce/

В частности, если вы также реализуете сервер авторизации, тогда https://www.oauth.com/oauth2-servers/oauth-native-apps/checklist-server-support-native-apps/ заявляет, что вам следует

  • Разрешить клиентам регистрировать настраиваемые схемы URL-адресов для своих URL-адресов перенаправления.
  • Поддержка петлевых URL-адресов перенаправления IP с произвольными номерами портов для поддержки настольных приложений.
  • Не думайте, что нативные приложения умеют хранить секреты. Требовать, чтобы все приложения объявляли, являются ли они общедоступными или конфиденциальными, и выдают секреты клиента только конфиденциальным приложениям.
  • Поддерживайте расширение PKCE и требуйте, чтобы его использовали общедоступные клиенты.
  • Попытка определить, когда интерфейс авторизации встроен в веб-представление собственного приложения, а не запущен в системном браузере, и отклонить эти запросы.

Рассмотрение веб-просмотров

Существует множество примеров использования веб-представлений, то есть встроенного пользовательского агента, но этого подхода следует избегать (особенно, когда приложение не является основным), и в некоторых случаях может привести к тому, что вам запретят использовать API в качестве выдержки. ниже из здесь демонстрируется

Любая попытка встроить страницу аутентификации OAuth 2.0 приведет к блокировке вашего приложения в Fitbit API.

В целях безопасности страница авторизации OAuth 2.0 должна быть представлена ​​в специальном представлении браузера. Пользователи Fitbit могут подтвердить, что они проходят аутентификацию на подлинном сайте Fitbit.com, только если у них есть инструменты, предоставляемые браузером, такие как адресная строка и информация о сертификате безопасности транспортного уровня (TLS).

Для собственных приложений это означает, что страница авторизации должна открываться в браузере по умолчанию. Собственные приложения могут использовать настраиваемые схемы URL-адресов в качестве URI перенаправления для перенаправления пользователя обратно из браузера в приложение, запрашивающее разрешение.

Приложения iOS могут использовать класс SFSafariViewController вместо переключения приложения на Safari. Использование классов WKWebView или UIWebView запрещено.

Приложения Android могут использовать пользовательские вкладки Chrome вместо переключения приложений на браузер по умолчанию. Использование WebView запрещено.

Для дальнейшего пояснения вот цитата из этого раздела предыдущей версии ссылки на передовой опыт, приведенной выше.

Встроенные пользовательские агенты, обычно реализуемые с помощью веб-представлений, являются альтернативным методом авторизации собственных приложений. Однако они по определению небезопасны для использования третьими сторонами. Они вовлекают пользователя, входящего в систему со своими полными учетными данными, только для того, чтобы они были переведены на менее мощные учетные данные OAuth.

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

В типичных реализациях встроенных пользовательских агентов на основе веб-представления хост-приложение может: регистрировать каждое нажатие клавиши, введенное в форму, для захвата имен пользователей и паролей; автоматически отправлять формы и обходить пользовательское согласие; копировать файлы cookie сеанса и использовать их для выполнения аутентифицированных действий в качестве пользователя.

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

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

В связи с вышеизложенным использование встроенных пользовательских агентов НЕ РЕКОМЕНДУЕТСЯ, за исключением случаев, когда доверенное основное приложение действует как внешний пользовательский агент для других приложений или обеспечивает единый вход для нескольких основных приложений.

Серверам авторизации СЛЕДУЕТ рассмотреть возможность принятия мер для обнаружения и блокировки входа через встроенные пользовательские агенты, которые не являются их собственными, где это возможно.

Здесь также поднимаются некоторые интересные моменты: https://security.stackexchange.com/questions/179756/why-are-developers-using-embedded-user-agents-for-3rd-party-auth-what-are-the-a

person Matt C    schedule 26.07.2016
comment
Google прекращает поддержку веб-просмотров 20 апреля 2017 г. developers.googleblog.com/2016/08/ - person Matt C; 09.03.2017
comment
К вашему сведению, документ ссылается на начало этого ответа, если это уже не черновик OAuth 2.0 для собственных приложений - tools.ietf. org / html / rfc8252 - person Kostiantyn Sokolinskyi; 28.01.2018
comment
Спасибо @KostiantynSokolinskyi, отредактировано соответствующим образом со ссылкой на RFC, которая больше не является черновиком - person Matt C; 23.03.2018
comment
@MattC Как лучше всего реализовать регистрацию нового пользователя? Что делать - в приложении или в IDP? Можно ли автоматически входить в регистр сообщений пользователя? stackoverflow.com/ questions / 60187173 / - person Yashvit; 13.02.2020
comment
Извините, я запутался в некоторых деталях ... Не могли бы вы взглянуть? Спасибо! ссылка --- ›stackoverflow.com/q/61313694/4619958 - person ch271828n; 20.04.2020

К сожалению, я не думаю, что на этот вопрос есть однозначный ответ. Однако вот варианты, которые я определил:

  • Если можно запросить у пользователя его / ее учетные данные, используйте учетные данные для пароля владельца ресурса. Однако это может быть невозможно по некоторым причинам, а именно:

    • Usability or security policies forbid the insertion of the password directly at the app
    • Процесс аутентификации делегируется внешнему поставщику удостоверений и должен выполняться через поток на основе перенаправления HTTP (например, OpenID, SAMLP или WS-Federation).
  • Если требуется использование потока на основе браузера, используйте поток кода авторизации. Здесь определение redirect_uri представляет собой серьезную проблему, для которой есть следующие варианты:

    • Use the technique described in https://developers.google.com/accounts/docs/OAuth2InstalledApp, where a special redirect_uri (e.g. urn:ietf:wg:oauth:2.0:oob) signals the authorization endpoint to show the authorization code instead of redirecting back to the client app. The user can manually copy this code or the app can try to obtain it from the HTML document title.
    • Используйте localhost сервер на устройстве (управление портом может оказаться непростым).
    • Используйте настраиваемую схему URI (например, myapp://...), которая при разыменовании запускает зарегистрированный «обработчик» (детали зависят от мобильной платформы).
    • Если возможно, используйте специальное "веб-представление", такое как WebAuthenticationBroker в Windows 8, для управления и получить доступ к ответам перенаправления HTTP.

Надеюсь это поможет

Педро

person Pedro Felix    schedule 02.07.2013
comment
Спасибо Педро за вклад !. Да, похоже, что поток кода авторизации с настраиваемой схемой URI или веб-представление кажется здесь лучшим вариантом. - person Pablo Cibraro; 02.07.2013
comment
Все зависит от того, хотите ли вы, чтобы клиент вводил пароль в веб-представлении или в клиентском приложении. Если возможно, я бы предпочел клиентское приложение - тогда сразу же обменивайтесь секретом с токеном доступа / обновления. - person leastprivilege; 02.07.2013
comment
Спасибо Доминик !. Мой клиент использует ADFS для аутентификации пользователей, поэтому они хотят ввести учетные данные на странице входа. Веб-просмотр будет работать для них - person Pablo Cibraro; 02.07.2013
comment
Мне любопытно, почему вы рекомендуете поток кода авторизации? Разве вам не понадобятся client_secret и client_id для обмена кода на access_token? Я думал, что неявный поток был разработан для этих сценариев, потому что он не требует хранения секретов на устройстве. - person Eugenio Pace; 02.07.2013
comment
implicit не поддерживает токены обновления OOB. В сценарии Пабло - я бы явно рекомендовал поток обратного осмоса. Похоже, компания развернула приложения на одном сервере. - person leastprivilege; 02.07.2013
comment
Я полагаю, что неявный поток предотвратит подобные вещи, верно? Threatpost.com/twitter-oauth-api-keys-leaked-030713 - person Pablo Cibraro; 02.07.2013
comment
Теоретически можно использовать поток кода с общедоступными клиентами. Однако должен быть способ создания клиентов для каждой установки, где client_secret назначается для конкретной установки. Я надеялся, что спецификация динамической регистрации клиентов предоставит некоторую поддержку для этого, но это не так. - person Pedro Felix; 02.07.2013
comment
@EugenioPace Я тоже рекомендую то же самое. Вам не нужно тратить время на создание собственной формы входа таким образом. Таким образом, интерфейс входа в систему зависит от службы, в которой вы выполняете аутентификацию, и это позволяет пользователю чувствовать себя более комфортно. - person Radu Simionescu; 18.02.2015
comment
Извините, я запутался в некоторых деталях ... Не могли бы вы взглянуть? Спасибо! ссылка --- ›stackoverflow.com/q/61313694/4619958 - person ch271828n; 20.04.2020

TL; DR: используйте предоставление кода авторизации с PKCE

1. Неявный тип гранта

Неявный тип гранта довольно популярен в мобильных приложениях. Но это не предназначалось для такого использования. Перенаправление связано с проблемами безопасности. Джастин Ричер заявляет:

Проблема возникает, когда вы понимаете, что, в отличие от URL-адреса удаленного сервера, не существует надежного способа гарантировать соблюдение привязки между заданным URI перенаправления и конкретным мобильным приложением. Любое приложение на устройстве может попытаться вставить себя в процесс перенаправления и заставить его обслуживать URI перенаправления. И угадайте, что: если вы использовали неявный поток в своем собственном приложении, то вы просто передали злоумышленнику свой токен доступа. С этого момента выхода нет - у них есть токен, и они могут его использовать.

И вместе с тем, что он не позволяет обновить токен доступа, лучше этого избегать.

2. Тип предоставления кода авторизации

Для предоставления кода авторизации требуется секрет клиента. Но вы не должны хранить конфиденциальную информацию в исходном коде вашего мобильного приложения. Люди могут их добыть. Чтобы не раскрывать секрет клиента, вы должны запустить сервер в качестве посредника, как пишет Facebook:

Мы рекомендуем использовать токены доступа к приложениям только непосредственно с серверов вашего приложения, чтобы обеспечить максимальную безопасность. Для нативных приложений мы предлагаем, чтобы приложение взаимодействовало с вашим собственным сервером, а затем сервер отправлял запросы API в Facebook, используя токен доступа к приложению.

Не идеальное решение, но есть новый, лучший способ использовать OAuth на мобильных устройствах: Proof Key for Code Exchange

3. Тип предоставления кода авторизации с PKCE (ключ подтверждения для обмена кодом)

Из-за ограничений был создан новый метод, позволяющий использовать код авторизации без секрета клиента. Вы можете прочитать полный RFC 7636 или это краткое введение.

PKCE (RFC 7636) - это метод защиты общедоступных клиентов, которые не используют секреты клиента.

Он в основном используется нативными и мобильными приложениями, но этот метод можно применить и к любому общедоступному клиенту. Он требует дополнительной поддержки со стороны сервера авторизации, поэтому поддерживается только некоторыми поставщиками.

из https://oauth.net/2/pkce/

person Johannes Filter    schedule 06.03.2018

Использование веб-просмотра в мобильном приложении должно быть доступным способом реализации протокола OAuth2.0 на платформе Android.

Что касается поля redirect_uri, я думаю, что http://localhost - хороший выбор, и вам не нужно переносить HTTP-сервер внутри вашего приложения, потому что вы можете переопределить реализацию функции onPageStarted в классе WebViewClient и прекратить загрузку веб-страницы из http://localhost после того, как вы проверьте параметр url.

public void onPageStarted(final WebView webView, final String url,
        final Bitmap favicon) {}
person Zephyr    schedule 20.02.2015
comment
Лучшие практики для собственных приложений с использованием OAuth2: tools.ietf.org/html/ draft-wdenniss-oauth-native-apps - person Matt C; 26.07.2016
comment
Как сказал Мэтт С. выше. Веб-представления - плохая идея для мобильных приложений - они небезопасны, позволяют приложению получать доступ к учетным данным (поэтому не более безопасны, чем RO) и не позволяют пользователям проверять домен и сертификаты TLS. Используйте тип предоставления кода аутентификации с настраиваемым обработчиком URI и убедитесь, что вы используете код подтверждения для обмена ключами ( PKCE), чтобы вредоносные приложения на вашем телефоне не перехватывали код аутентификации и не получали доступ к вашему API. - person ChrisC; 01.08.2016
comment
Обновленная версия проекта документа с рекомендациями по использованию OAuth 2.0 для собственных приложений находится по адресу tools .ietf.org / html / draft-ietf-oauth-native-apps. - person Jeff Olson; 26.09.2016

Самый удобный и простой в реализации пользовательский интерфейс для аутентификации - это встроить веб-просмотр в ваше приложение. Обработайте ответы, полученные веб-просмотром от точки аутентификации, и обнаружите ошибку (отмена пользователя) или утверждение (и извлеките токен из параметров запроса URL). И я думаю, что вы действительно можете сделать это на всех платформах. Я успешно выполнил эту работу для следующих устройств: ios, android, mac, приложения для Windows Store 8.1, приложения для Windows Phone 8.1. Я сделал это для следующих сервисов: dropbox, google drive, onedrive, box, basecamp. Для платформ, отличных от Windows, я использовал Xamarin, который якобы не раскрывает все API-интерфейсы, специфичные для платформы, но при этом предоставляет достаточно, чтобы это стало возможным. Так что это довольно доступное решение даже с точки зрения кроссплатформенности, и вам не нужно беспокоиться о пользовательском интерфейсе формы аутентификации.

person Radu Simionescu    schedule 17.02.2015
comment
Обеспечивая удобный пользовательский интерфейс, мы увидим, что отрасль отойдет от этого подхода. Поскольку веб-представления открывают возможность компрометации паролей, когда встроенный пользовательский агент запрашивает учетные данные, я удаляю приложение. Некоторые API теперь даже запрещают такие интеграции, такие как этот dev.fitbit.com/docs/oauth2 - person Matt C; 26.07.2016
comment
Лучшие практики для собственных приложений с использованием OAuth2: tools.ietf.org/html/ draft-wdenniss-oauth-native-apps - person Matt C; 26.07.2016
comment
Я не понимаю, как сервис с поддержкой oauth может запретить такой подход. Это необнаружимо и безопасно ... Некоторые службы с поддержкой oauth предоставляют клиентов для конкретных платформ, чтобы упростить аутентификацию, и такие клиенты фактически делают то, что я описал здесь (показывают встроенное веб-представление и отслеживают изменения URL-адресов). Лучшая практика, которую вы связали, рекомендует то же самое: использовать системный браузер или встроенный веб-просмотр. На какой аргумент вы нападаете из моего ответа? непонятно. - person Radu Simionescu; 26.07.2016
comment
Атака не предполагалась, просто выдвигала на первый план проблему. В ссылке говорится, что есть два упомянутых вами подхода, но только внешний пользовательский агент может считаться безопасным, в частности, в нем говорится, что параметры для собственных приложений доступны через встроенный пользовательский агент или внешний пользовательский агент. Этот документ рекомендует внешние пользовательские агенты, такие как вкладки браузера в приложении, как единственный безопасный и удобный выбор для OAuth. - person Matt C; 26.07.2016
comment
Дополнительная цитата В типичных реализациях встроенных пользовательских агентов на основе веб-представления хост-приложение может: регистрировать каждое нажатие клавиши, введенное в форму, для захвата имен пользователей и паролей; автоматически отправлять формы и обходить согласие пользователя ....... использование встроенных пользовательских агентов НЕ РЕКОМЕНДУЕТСЯ, за исключением случаев, когда доверенное собственное приложение действует как внешний пользовательский агент для других приложений или обеспечивает единый вход для нескольких сторонних приложений. Серверам авторизации СЛЕДУЕТ рассмотреть возможность принятия мер для обнаружения и блокировки входа через встроенные пользовательские агенты, которые не являются их собственными, где это возможно. - person Matt C; 26.07.2016
comment
Обновленная версия проекта документа с рекомендациями по использованию OAuth 2.0 для собственных приложений находится по адресу tools .ietf.org / html / draft-ietf-oauth-native-apps. - person Jeff Olson; 26.09.2016