- Вопрос или проблема
- Ответ или решение
- Использование clientSecret в OAuth2 (Azure) для SPA и бэкенда
- Введение
- Работа вашей системы
- Рекомендации по использованию clientSecret
- 1. Где использовать clientSecret?
- 2. Почему не использовать clientSecret в SPA?
- Устранение уязвимостей
- 1. Серверная проверка токена
- 2. Конфигурация Azure
- Заключение
Вопрос или проблема
У нас есть браузерное приложение (одностраничное приложение на JavaScript) с аутентификацией через Azure OAuth2, которое также подключается к серверу на заднем плане через REST API. Текущая реализация работает следующим образом:
- на главной странице есть кнопка
SSO Login
- браузерное приложение вызывает
https://login.microsoftonline.com/$tenantId/oauth2/v2.0/authorize?client_id=$appId&response_mode=fragment&response_type=code&scope=email%20openid%20profile%20offline_access&redirect_uri=https://appurl&code_challenge=..&..
, чтобы начать процесс входа в Azure. - (специфичные для Azure перенаправления и веб-страницы для выбора учетной записи)
- Azure перенаправляет обратно в приложение
https://appurl#code=ABC..&client_info=..&..
- Приложение делает POST-запрос на
https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token
с полезной нагрузкойclient_id=$appId&redirect_uri=https://appurl&code=ABC..&code_verifier=..&grant_type=authorization_code&..
- Ответ содержит JSON с полями
access_token, id_token
Приложение отправляет значение id_token
без изменений на бэкенд /rest/login
.
- токен проверяется на бэкенде по
подписывающему ключу от Azure, сроку действия, аудиенции, эмитенту
. - читаются поля
sub,name,email,roles[]
из токена. - создается внутренний идентификатор сессии и возвращается JSON клиентскому JS приложению.
- клиент использует идентификатор сессии в REST-запросе в виде
Authorization: Bearer xxAppSessionIdxx
- на этом этапе Azure
id_token
забывается, так как мы знаем значения пользователя и роли.
Клиент спросил нас, где мы помещаем значение clientSecret
, оно доступно на странице регистрации приложения в Azure. Мы его не используем.
Вопрос Должны ли мы его использовать и где? Пытаясь прочитать документацию, мы не получили полного ответа на вопрос, и некоторые страницы говорят, что clientSecret не следует использовать в SPA-приложениях, так как значение больше не является секретом в JavaScript браузерных приложениях
.
Является ли наша система менее безопасной на данный момент? Что следует сделать, чтобы улучшить её, например, так?
- клиент делает первый OAuth авторизационный запрос на сегодняшний день
- клиент отправляет значение
#id_code=ABC..
на бэкенд - бэкенд делает запрос Azure
/oauth2/v2.0/token
, чтобы преобразовать «бессмыслицу» в значение id_token jwt, сегодня это происходит в клиентском приложении. - создается внутренний идентификатор сессии и возвращается JSON клиентскому JS приложению.
Существуют ли настройки приложения Azure, чтобы заставить использовать clientSecret
, чтобы никто не мог вызвать /oauth2/v2.0/token
без него? Это значение остается на бэкенде, поэтому его трудно угадать просто проверяя вкладку сети браузера.
Ответ или решение
Использование clientSecret в OAuth2 (Azure) для SPA и бэкенда
Введение
В процессе реализации авторизации через OAuth2 с использованием Azure, важно понимать, как и когда использовать параметр clientSecret
. В вашем текущем варианте решения клиентская часть (SPA) взаимодействует с Azure для получения токенов, но это приводит к вопросам безопасности, особенно в свете того, что clientSecret
не применяется.
Работа вашей системы
Согласно описанию, ваша система состоит из следующих шагов:
- Клиент инициирует аутентификацию через кнопку "SSO Login".
- Выполняется редирект на Azure для аутентификации пользователя.
- После успешной аутентификации Azure возвращает код авторизации.
- Клиент отправляет данный код на Azure, чтобы получить
access_token
иid_token
. id_token
отправляется на бэкенд для проверки.- На бэкенде создается внутренний идентификатор сессии на основе данных токена.
Рекомендации по использованию clientSecret
1. Где использовать clientSecret?
clientSecret
является конфиденциальной информацией и должен храниться на серверной стороне (бэкенд).
- Пользовательский запрос на /oauth2/v2.0/token: Замените текущую логику определения токена в клиенте на серверный вызов API. После получения кода авторизации от Azure (после редиректа на ваш
redirect_uri
), отправьте этот код на бэкенд. В бэкенде произведите запрос к Azure/oauth2/v2.0/token
, включив в него:client_id
client_secret
redirect_uri
code
grant_type=authorization_code
Эта доработка предотвратит злоупотребление из-за того, что пользователи SPA не смогут получить access_token
напрямую.
2. Почему не использовать clientSecret в SPA?
В браузерных приложениях, таких как SPA, clientSecret
нельзя использовать, поскольку:
- JavaScript код может быть извлечен злоумышленниками.
- Это делает ваш
clientSecret
доступным для всех, что ставит под угрозу безопасность вашего приложения.
Поэтому настоятельно рекомендуется использовать clientSecret
только на серверной стороне.
Устранение уязвимостей
1. Серверная проверка токена
Запросы к /oauth2/v2.0/token и проверка полученных токенов должны выполняться только на вашем бэкенде для повышения безопасности:
- Убедитесь, что токены проверяются на сервере, где вы сможете использовать
clientSecret
. - Сервер может хранить сессии и управлять авторизацией пользователей безопасно.
2. Конфигурация Azure
Лимитирование функций приложения в Azure может быть осуществлено через настройки:
- Перейдите в
Authentication
вашей зарегистрированной Azure App и настройте параметры, которые позволят контролировать доступ к токенам. - Вы можете использовать дополнительные API Management и Conditional Access Policies для обеспечения безопасности.
Заключение
На текущий момент ваша система может быть менее защищенной из-за отсутствия применения clientSecret
в процессе получения токенов. Рекомендуется переместить логику получения токенов на бэкенд, чтобы использовать clientSecret
безопасно и эффективно. Это обеспечит лучший контроль безопасности, уменьшит риски утечки конфиденциальных данных и повысит защиту вашего приложения.