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

87

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

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

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

Пабло Сибраро
источник
1
Возникает вопрос: является ли это высшим приоритетом, когда пользователю никогда не придется снова вводить пароль после первого входа в систему?
lessprivilege 02
Да, это именно мое требование. Пользователь должен ввести пароль только один раз. Однако я не хочу настраивать токен с бесконечным сроком жизни и хранить его в мобильном приложении, так как это противоречит возможности отзыва токена. (Если я не добавлю логику в мобильное приложение, чтобы обнаружить, что запрос был несанкционированным, поэтому я запрашиваю новый токен после этого)
Пабло Сибраро 02
1
Вы можете добавить токен с бесконечным сроком жизни и при этом отозвать его. И да, логика приложения должна уметь это определять. RFC 6750 определяет способ проверки, вызвана ли ошибка отозванным токеном.
Педро Феликс
1
Пожалуйста, избегайте веб-представлений (если только вы не владеете полным стеком и не используете социальный вход), которые открывают возможность взлома паролей. Когда сторонний встроенный пользовательский агент запрашивает учетные данные, я удаляю приложение. Некоторые API-интерфейсы теперь даже запрещают такие интеграции, такие как этот dev.fitbit.com/docs/oauth2. Я дал еще один ответ, чтобы прояснить некоторые из этих концепций ( stackoverflow.com/a/38582630/752167 )
Мэтт К.

Ответы:

90

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

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

Рекомендации по 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, только если у них есть инструменты, предоставляемые браузером, такие как URL-адрес и информация о сертификате безопасности транспортного уровня (TLS).

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

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

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

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

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

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

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

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

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

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

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

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

Мэтт С
источник
3
Google прекращает поддержку веб-просмотров 20 апреля 2017 года developers.googleblog.com/2016/08/…
Matt C,
К вашему сведению, документ ссылается на начало этого ответа, если это не черновик OAuth 2.0 для собственных приложений - tools.ietf.org/html/rfc8252
Константин Соколинский
Спасибо @KostiantynSokolinskyi, отредактировано соответствующим образом со ссылкой на rfc, который больше не является черновиком
Matt C
@MattC Как лучше всего реализовать регистрацию нового пользователя? Что делать - в приложении или в IDP? Можно ли автоматически входить в регистр сообщений пользователя? stackoverflow.com/questions/60187173/…
Яшвит
Извините, я запутался в некоторых деталях ... Не могли бы вы взглянуть? Благодарность! ссылка ---> stackoverflow.com/q/61313694/4619958
ch271828n
25

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

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

    • Политики удобства использования или безопасности запрещают ввод пароля прямо в приложении.
    • Процесс аутентификации делегируется внешнему поставщику удостоверений и должен выполняться через поток на основе перенаправления HTTP (например, OpenID, SAMLP или WS-Federation).
  • Если требуется использование потока на основе браузера, используйте кода авторизации . Здесь определение термина redirect_uriявляется серьезной проблемой, для которой существуют следующие варианты:

    • Используйте технику, описанную в https://developers.google.com/accounts/docs/OAuth2InstalledApp , где специальный redirect_uri(например urn:ietf:wg:oauth:2.0:oob) сигнализирует конечной точке авторизации, чтобы показать код авторизации вместо перенаправления обратно в клиентское приложение. Пользователь может вручную скопировать этот код или приложение может попытаться получить его из заголовка HTML-документа.
    • Используйте localhostсервер на устройстве (управление портом может оказаться непростым).
    • Используйте настраиваемую схему URI (например myapp://...), которая при разыменовании запускает зарегистрированный «обработчик» (детали зависят от мобильной платформы).
    • Если возможно, используйте специальное «веб-представление», такое как WebAuthenticationBroker в Windows 8, для управления и доступа к ответам перенаправления HTTP.

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

Педро

Педро Феликс
источник
Спасибо Педро за вклад !. Да, похоже, что поток кода авторизации с настраиваемой схемой URI или веб-представление кажется здесь лучшим вариантом.
Пабло Сибраро 02
1
Все зависит от того, хотите ли вы, чтобы клиент вводил пароль в веб-представлении или в клиентском приложении. Если возможно, я бы предпочел клиентское приложение - тогда сразу же обменяй секрет на токен доступа / обновления.
lessprivilege 02
Спасибо Доминик !. Мой клиент использует ADFS для аутентификации пользователей, поэтому они хотят ввести учетные данные на странице входа. Веб-просмотр будет работать для них
Пабло Сибраро 02 июл.13,
5
Мне любопытно, почему вы рекомендуете «поток кода авторизации»? Разве вам не понадобятся client_secret и client_id для обмена кода на access_token? Я думал, что «неявный» поток был разработан для этих сценариев, потому что он не требует хранения секретов на устройстве.
Eugenio Pace
1
implicit не поддерживает токены обновления OOB. В сценарии Пабло я бы явно рекомендовал поток обратного осмоса. Похоже, компания развернула приложения на одном сервере.
lessprivilege 02
9

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/

Johannes Filter
источник
-3

Использование веб-просмотра в вашем мобильном приложении должно быть доступным способом реализации протокола 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) {}
Зефир
источник
3
Лучшие практики для собственных приложений с использованием OAuth2: tools.ietf.org/html/draft-wdenniss-oauth-native-apps
Matt C,
1
Как сказал Мэтт С. выше. Веб-представления - плохая идея для мобильных приложений - они небезопасны, позволяют приложению получать доступ к учетным данным (поэтому не более безопасны, чем RO) и не позволяют пользователям проверять домен и сертификаты TLS. Используйте тип предоставления Auth Code с настраиваемым обработчиком URI и убедитесь, что вы используете Proof Code for Key Exchange (PKCE), чтобы не дать вредоносным приложениям на вашем телефоне перехватить код аутентификации и получить доступ к вашему API.
ChrisC 01
2
Обновленная версия проекта документа с рекомендациями
Джефф Олсон,
-4

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

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