Я создаю новое приложение с набором микросервисов и интерфейсом с помощью React. У меня есть собственный сервер аутентификации, использующий Oauth. В идеале я хочу сохранить процесс входа и регистрации пользователя в приложении React, поскольку я владею как сервером аутентификации, так и клиентским приложением.
Я хотел использовать предоставление пароля, но из-за того, что React является одностраничным приложением, я не могу защитить секрет. Я могу использовать неявное предоставление, но на самом деле не хочу перенаправлять пользователя на другую страницу для входа или регистрации. Это было бы нормально для будущей интеграции с третьими сторонами, но, поскольку я владею интерфейсом, я хочу сделать его максимально простым (например, как Facebook).
В качестве альтернативы, могу ли я создать микросервис пользователя (где я могу защитить секрет), который предоставляет API для входа и регистрации, которые затем вызывают службу аутентификации с использованием предоставления пароля?





Я считаю, что вы хотите иметь "Предоставление учетных данных для пароля владельца ресурса". В этом потоке Oauth 2 конечный пользователь (владелец ресурса) предоставляет клиенту свои учетные данные, доверяя клиенту. Клиент использует эти учетные данные для обмена токеном с сервера авторизации. Ваш внешний интерфейс не должен хранить учетные данные. Но, как всегда, потребуется хранить токены.
Как только клиентская часть получит токены, она сможет обмениваться данными с вашими серверами. И они должны быть защищены токенами, которые вы проверяете на сервере авторизации.
@Swordfish О каком секрете ты говоришь? Если это учетные данные владельца ресурса, вам не нужно его защищать. Это должно быть что-то вроде простого экрана входа в систему, который запустит поток для получения токенов.
Я думаю, что он имел в виду секрет клиента. Чтобы использовать поток паролей владельца ресурса, вам необходимо предоставить учетные данные клиента.
Я думаю, под секретом вы имели в виду секрет клиента?
Поскольку React - это javascript, вы не можете защитить секрет клиента и не хотите использовать неявное предоставление, наличие службы / микросервиса в качестве серверной части пользовательского интерфейса - хороший подход. Бэкэнд пользовательского интерфейса может защищать секреты клиента и создавать токены с помощью вашего сервера OAuth. Затем интерфейсная часть пользовательского интерфейса вызовет API-интерфейс внутренней части пользовательского интерфейса. Бэкэнд пользовательского интерфейса может использовать тип предоставления password для создания токенов при входе пользователя в систему.
Да это секрет клиента. Я попытаюсь создать этот микросервис «прокси», который будет предоставлять API входа и регистрации и внутренне вызывать службу аутентификации. Есть ли какие-либо другие соображения безопасности, которые мне нужно будет реализовать с помощью этого подхода?
У вас здесь две проблемы.
Один из них - как аутентифицировать SPA без утечки client_ secret, а второй - как безопасно хранить токен доступа во внешнем интерфейсе после решения первой проблемы.
Я бы порекомендовал этот подход
Создайте внутренний прокси-сервер, работающий на том же доменном имени, что и ваш SPA - он все еще может быть вашим сервером аутентификации.
Затем вы можете отправить учетные данные из своего SPA на этот прокси-сервер, чтобы ваш пользователь прошел проверку подлинности с помощью предоставления пароля.
После аутентификации вы можете вернуть клиенту access_token (или обычную аутентификацию на основе сеанса) через безопасный http cookie, который сделает ваши запросы SPA API аутентифицированными через cookie.
Это создаст еще одну проблему, о которой вам нужно позаботиться. CSRF - вы можете сгенерировать токен CSRF, отправить его клиенту через обычный файл cookie XSRF-TOKEN, который будет автоматически выбран вашим http-клиентом, как axies, и возвращен на сервер через заголовок X-XSRF-TOKEN.
Как только токен csrf получен прокси-сервером, вы можете сравнить его с токеном в файле cookie или с токеном в вашем сеансе, прежде чем разрешить продолжение запроса.
Также стоит обратить внимание на защиту заголовков CORS и обеспечение того, чтобы сервером принимались только запросы от вашего доменного имени SPA.
Я считаю, что это причина создания PKCE. CSRF-атаки можно предотвратить, выполнив вызов на лету и без использования секрета.
PKCE (RFC 7636) is an extension to the Authorization Code flow to prevent several attacks and to be able to securely perform the OAuth exchange from public clients.
It was originally designed to protect mobile apps, but its ability to prevent authorization code injection makes it useful for every OAuth client, even web apps that use a client secret.
См. Также rfc7636
Проблема в том, что я не могу защитить секрет, поскольку интерфейс представляет собой одностраничное приложение, созданное с использованием React.