Введение в стороннюю авторизацию и рефакторинг процесса аутентификации

Введение в стороннюю авторизацию и рефакторинг процесса аутентификации

Недавно Vizend представил и переработал функцию входа через сторонние сервисы. Вход через сторонние сервисы позволяет проверять пользователя с помощью внешних методов аутентификации, таких как Google, Apple, Facebook и Keycloak, связывая результат с внутренней системой пользователей Vizend. На экране для пользователя это выглядит как кнопка «Войти с помощью внешней учетной записи», но с точки зрения сервера ключом является то, как связать результат внешней аутентификации с внутренними учетными записями, политиками подписки, политиками связывания учетных записей и политиками сессий.

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

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

Фон приложения

Ворота Vizend — это общая основа аутентификации, используемая в нескольких сервисах. Хотя каждый сервис мог бы реализовать вход через Google, вход через Apple и вход через Keycloak непосредственно, сделать это означало бы разбросать политики аутентификации по сервисам. Изначально это может показаться быстрее, но по мере добавления новых провайдеров и сервисов операционные расходы увеличиваются, что затрудняет понимание масштаба воздействия в случае изменения политик.

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

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

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

  • Поглощать различия в методах аутентификации по провайдерам в общий поток в рамках Ворот.

  • Разрешать различные настройки для провайдеров и политик регистрации по организациям.

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

  • Ясно разграничить новые регистрации и связывания существующих учетных записей.

  • Сохранять статус внутренних пользователей, права и политики сессий даже после внешней аутентификации.

Направление проектирования

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

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

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

Мы решили управлять политиками как настройками, специфичными для компании, вместо того чтобы жестко их закодировать. Настройки внешнего входа могут изменяться даже в процессе работы. URI перенаправления может измениться, миры Keycloak могут быть разделены, и определенные провайдеры могут потребовать временной деактивации. Если эти значения встроены в код, даже незначительные изменения в работе потребуют развёртывания. Отделив их как политики, мы можем более гибко реагировать на корпоративном уровне.

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

Общий поток

Общий поток входа через ThirdParty может быть организован в порядке внешней аутентификации, проверки Gate, сопоставления внутренних пользователей и регистрации или связывания. Сначала пользователь выполняет аутентификацию с провайдерами, такими как Google, Apple и Keycloak, с клиента. Когда аутентификация провайдера завершена, клиент передаёт полученные удостоверения в Gate.

image1.png

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

Если использование провайдера разрешено, Gate проверяет удостоверения и извлекает внешнюю информацию о пользователе. На этом этапе возникают различия для каждого провайдера. Google, Facebook, Apple и Keycloak имеют разные способы проверки информации о пользователе и форматы ответов. Тем не менее, внутри Gate это преобразуется в общую информацию о пользователе и передается на следующий шаг.

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

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

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

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

Обработка провайдерских отличий

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

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

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

Keycloak близок к стандартному потоку OIDC, но сильно зависит от конфигурации. Метод обмена токенами и получения информации о пользователе может различаться в зависимости от области, клиента, URI перенаправления и метода аутентификации клиента. Особенно при интеграции с клиентскими компаниями или внутренними IdP конечная точка и метод аутентификации клиента могут различаться в зависимости от окружения, поэтому важно настраивать политику.

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

Разделение новых регистраций и связывания с существующими аккаунтами

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

image2.png

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

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

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

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

Автоматическое связывание на основе электронной почты

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

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

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

Связывание на основе электронной почты требует баланса между удобством и безопасностью. В ThirdParty входе Vizend поток был разделен с учетом как статуса проверки электронной почты по провайдеру, так и статуса дублирования среди внутренних пользователей.

Роль токена регистрации

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

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

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

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

Результаты приложения

После внедрения и рефакторинга входа через ThirdParty поток был разделен на реализации, специфичные для провайдера, и доменные политики. Хотя Google, Facebook, Apple и Keycloak имеют разные методы аутентификации, они могут обрабатываться в одном и том же потоке в Gate. Различия между провайдерами организованы заранее, а затем применяются внутренние соответствия пользователей, политики регистрации и политики связывания аккаунтов в единообразной форме.

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

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

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

Резюме

Вход через ThirdParty — это не просто простой вызов API OAuth, а поток аутентификации, который соединяет результаты внешней аутентификации с внутренней моделью пользователя. Хотя это выглядит как одна кнопка на экране пользователя, внутри сервера внешняя аутентификация, внутренний статус пользователя, политики регистрации, связывания аккаунтов и политики сессий все связаны. Если этот поток не четко разграничен, реализация может показаться быстрой, но возникнут проблемы с операцией и масштабируемостью.

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

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

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

Дэвид

Site footer