Организация безопасного канала между веб-приложением и собственным приложением - PullRequest
7 голосов
/ 25 марта 2019

Этот вопрос является своего рода дополнительным к " Обмен учетными данными между собственным приложением и веб-сайтом ", поскольку мы стремимся делиться секретами в обратном направлении.

TL; TR: как мы можем безопасно передавать состояние аутентификации / авторизации пользователя из приложения веб-браузера в приложение Native Desktop, чтобы одному и тому же пользователю не приходилось дополнительно проходить аутентификацию в приложении Native?

TS; WM: Мы работаем над следующей архитектурой: веб-приложение (с некоторым интерфейсом пользовательского интерфейса HTML, работающим в веб-браузере по выбору пользователя), приложение Native Desktop (реализующее пользовательский обработчик протокола), вебAPI и сервис OAuth2, как на рисунке.

Первоначально пользователь аутентифицируется / авторизуется в приложении веб-браузера для сервиса OAuth2, используя поток предоставления кода авторизации,

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

Мы считаем, что , прежде чем действовать на основании любых запросов, полученных по каналу настраиваемого протокола из веб-браузера приложение Native должно сначала аутентифицировать пользователя (который должен быть тем же человеком, который использует этот конкретный сеанс рабочего стола).Мы считаем, что родное приложение должно также использовать поток кода авторизации (с PKCE) для получения токена доступа для веб-API.Затем он сможет безопасно проверять происхождение и целостность данных настраиваемого протокола, используя тот же веб-API.

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

Таким образом, вопрос: есть ли способ передать токен доступа OAuth2 (или любой другойдругой носитель авторизации) из приложения веб-обозревателя в приложение Native безопасно, без ущерба для безопасности этой архитектуры на стороне клиента? Т.е., чтобы приложение Native могло вызывать веб-API с использованием идентификатора из веб-обозревателя, не имеясначала аутентифицировать того же пользователя?

Лично я не вижу, как мы можем безопасно избежать этого дополнительного потока аутентификации.Связь по протоколу пользовательского приложения по умолчанию небезопасна, так как обычно это просто аргумент командной строки, с помощью которого вызывается Native.В отличие от канала TLS, он может быть перехвачен, подделан и т. Д. Мы могли бы зашифровать данные пользовательского протокола.Тем не менее, независимо от того, какие вызовы родному приложению нужно будет выполнить для его дешифрования (либо к API клиентской ОС, либо к некоторым незащищенным вызовам веб-API), плохой субъект или вредоносное ПО также может их реплицировать.

Я что-то пропустил?Есть ли безопасное решение для платформы?Приложение Native Desktop является приложением Electron и предназначено для кроссплатформенности.Большинство наших пользователей будут запускать это в Windows, используя любой поддерживаемый браузер (включая даже IE11), но об ActiveX или взломе работающего экземпляра веб-браузера не может быть и речи.

Ответы [ 5 ]

2 голосов
/ 03 апреля 2019

Вы думали об использовании LDAP или Active Directory?

Также можно объединить OAuth2, вот связанный вопрос:
- Сервис Oauth для аутентификации LDAP
- Маркер Oauth 2 для учетных записей Active Directory

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

Что касается общих соображений безопасности, вы можете работать с двумя серверами и перенаправлять с одного веб-приложения на другой после успешной проверки доступа. Этот 2-й сервер может быть защищен настолько, что с 1-го сервера требуется перенаправление, и проверка доступа может быть снова сделана независимой, но без необходимости входа в систему в другой раз, может быть важно упомянуть здесь предлагаемое использование Oracle Access Manager в одном связанном ответ за perimeter authentication.
Этот сценарий с двумя серверами можно также скрыть, используя прокси-сервер во внешнем интерфейсе и сделав перенаправления скрытыми, так что передача данных между серверами будет проще и безопаснее. Важным моментом в моем предложении является то, что доступ ко 2-му серверу просто не предоставляется, если что-то не так и данные все еще защищены.

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

Если вам нравится общая идея, я готов потратить еще некоторое время на детали. Некоторые вопросы могут быть полезны для меня; -)

EDIT:
Технически дизайн в деталях может зависеть от используемого external authentication provider типа Oracle Access Manager или чего-то еще. Поэтому, если решение в целом кажется вам разумным, было бы полезно разработать некоторые параметры для выбора external authentication provider, т.е. цены, открытого исходного кода, функций и т. Д.
Тем не менее, общая процедура заключается в том, что провайдер выдает токен, и этот токен служит для аутентификации. Токен предназначен для уникального одноразового использования. Вторая ссылка, которую я разместил выше, содержит несколько ответов, которые очень хорошо объясняют использование токена, связанное с безопасностью и OAuth.

EDIT2
Разница между собственным OAuth2 / OIDC-сервером и LDAP / AD-сервером заключается в том, что вам нужно все программировать самостоятельно, и вы не можете использовать готовые решения. Тем не менее, вы независимы, и если все хорошо запрограммировано, возможно, даже немного более безопасно, поскольку ваше решение не является общедоступным и, следовательно, труднее взломать - потенциальные уязвимости просто не могут быть известны другим. Кроме того, вы более независимы, вам никогда не придется ждать обновлений и вы можете изменить все, что вы хотите в любое время. Учитывая, что задействовано несколько программных серверов и, возможно, даже аппаратных серверов, собственное решение может быть ограничено в масштабах, но об этом нельзя знать извне и зависит от вашей компании / команды. Ваша кодовая база, вероятно, тоньше, чем полноценные решения, поскольку вам нужно только рассмотреть собственное решение и требования.
Слабым местом вашего решения может быть то, что вам нужно программировать интерфейсы для нескольких существующих вещей, готовых для бизнес-фреймворков. Также может быть сложно рассмотреть каждую точку в небольшой команде, у крупных компаний может быть больше обзора и возможностей для решения каждой потенциальной проблемы.

2 голосов
/ 02 апреля 2019

Вы можете попробовать запустить синхронизацию другим способом:

  1. После проверки подлинности пользователя в веб-приложении запустите собственное приложение из веб-приложения по пользовательской схеме URL.
  2. Если собственное приложение не аутентифицировано, надежно подключитесь к бэкэнду по HTTPS, создайте запись для собственного приложения, получите одноразовый токен, связанный с этой записью, а затем запустите веб-приложение в браузере пользователя с токеном как параметр URL.
  3. Поскольку пользователь проходит проверку подлинности в браузере, когда сервер видит токен, он может связать запись собственного приложения с учетной записью пользователя.
  4. Проведите собственный опрос приложений (или используйте какой-либо другой канал в реальном времени, например push-уведомления или TCP-соединение) на сервере, чтобы узнать, был ли токен привязан к учетной записи пользователя: как только это произойдет, вы можете передать постоянный токен аутентификации, который Нативное приложение может хранить.
2 голосов
/ 27 марта 2019

Просто пришла следующая идея. Это просто, и хотя оно не позволяет полностью автоматизировать настройку безопасного канала между приложением Web Browser и приложением Native, оно может значительно улучшить взаимодействие с пользователем.

Мы можем использовать Алгоритм одноразового пароля на основе времени (TOTP) . В некотором смысле это похоже на то, как мы подключаем Bluetooth-клавиатуру к компьютеру или телефону.

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

Все еще открыт для других идей.

2 голосов
/ 29 марта 2019

Лучшее решение: единый вход (SSO) с использованием пользовательской схемы URL

Когда я проверял ваш вопрос, я вспомнил приложение Zoom, которое я использую в своем офисе. Как это устроено ?

Моя учетная запись Gmail связана с учетной записью Zoom (это привязка учетной записи, которая выходит за рамки реализации). Когда я открываю приложение Zoom, я могу выбрать опцию входа в Gmail. Это откроет мой браузер и переместит меня в Gmail. Если я вошел в Gmail, меня перенаправили обратно на страницу с просьбой запустить приложение Zoom. Как происходит запуск этого приложения? Приложение регистрирует пользовательскую схему URL , когда приложение устанавливается, и конечный редирект в браузере нацелен на этот URL. И этот URL передает временный секрет, который приложение Zoom использует для получения токенов OAuth. И получение токена осуществляется независимо от браузера, прямой вызов с помощью SSL на конечную точку токена сервера OAuth.

Ну, это поток кода авторизации для нативных приложений. И вот как мобильные приложения используют OAuth. Ваша основная проблема, не позволяющая пользователю повторно войти в систему, решена. Это SSO в действии.

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

Вызов

Для каждого дистрибутива приложения необходимо реализовать собственный код для конкретной ОС. Windows, Mac и Linux имеют различную поддержку реализации пользовательской схемы URL.

Обратить

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

How PKCE protects token stealing

С PKCE ответ перенаправления / обратного вызова защищен от кражи. Даже какое-то другое приложение перехватывает обратный вызов, запрос токена не может быть воссоздан, так как есть PKCE code_verifer.

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

-------------------------------------------- ---------

Обновление: запрос защиты токена

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

- Связать запуск собственного приложения с секретным ключом из браузера

Когда клиент на основе браузера запускает собственный клиент, он может вызывать пользовательский API для генерации секрета. Этот секрет действует как одноразовый пароль (OTP). Пользователь должен ввести это значение в нативное приложение, прежде чем получить токены. Это настройка поверх потока кода авторизации.

- Динамическая регистрация клиента и Динамическая аутентификация клиента

Внедрение секретов в общедоступные клиенты не рекомендуется в соответствии со спецификацией OAuth. Но, как указывает владелец вопроса, некоторые вредоносные приложения могут зарегистрироваться, чтобы получить пользовательский URL-ответ и получить токены. В этом случае PKCE может обеспечить дополнительный уровень безопасности.

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

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

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

Резюме

  • Использовать пользовательскую схему URL для запуска собственного приложения
  • Приложение-браузер генерирует временный секрет для общего доступа к пользовательской службе
  • При запуске собственного приложения пользователь должен скопировать секрет в пользовательский интерфейс собственного приложения
  • Собственное приложение обменяет этот секрет с пользовательской службой для получения токена
  • Этот второй токен в сочетании с кодом авторизации обратного вызова (выданным по специальной схеме URL) используется для аутентификации в конечной точке токена
  • Выше можно рассматривать как динамическую аутентификацию клиента
  • Значение, предоставляемое пользователю, может быть хешированным секретом, следовательно, исходное значение никогда не раскрывается конечному пользователю или другому клиенту
  • DCR также возможен, но встроенные секреты не приветствуются в мире OAuth
2 голосов
/ 26 марта 2019

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

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

Представьте, что если бы это было возможным, то PKCE был бы избыточен в потоке кода OAuth 2.0, поскольку сервер мог бы безопасно передать токен доступа вответ на запрос авторизации, вместо того, чтобы требовать code_verifier предоставления гранта при получении токена доступа.

...