Как обрабатывать несколько серверов авторизации, чтобы предотвратить сбой при выдаче токена

#asp.net-core #identityserver4

Вопрос:

Настройка: У меня есть два сервера, на обоих из которых есть отдельный экземпляр IIS моего приложения для авторизации OpenID .NET Core.

Периодически возникает проблема, из-за которой, если запрос пользователя был запущен на сервере 1, в какой-то момент во время запросов запрос пользователя перемещается на сервер 2, затем происходит сбой авторизации со следующим сообщением:

     Invoking IdentityServer endpoint: IdentityServer4.Endpoints.TokenEndpoint for /connect/token

    ...

    fail: IdentityServer4.Validation.TokenRequestValidator[0]

    Invalid authorization code{ code = REDACTED }, details: {

    ...

    "GrantType": "authorization_code",
    "Error": "invalid_grant",
    "Category": "Token",
    "Name": "Token Issued Failure",
    "EventType": "Failure",
 

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

Как мне разрешить обоим моим серверам принимать запросы на /подключение/токен, даже если запрос был запущен на противоположном сервере?

Ответ №1:

Есть много вещей, которые вам нужно отслеживать при использовании балансировщиков нагрузки.

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

У вас есть еще один экземпляр сервера идентификации с несколькими экземплярами? независимо от этого вы также должны предоставить правильный ключ подписи токена и не использовать метод AddDeveloperSigningCredential в своем классе запуска.

Когда пользователя просят войти в систему, экземпляр (с AddOpenIDConnect) должен быть тем же экземпляром, который также обрабатывает обратный вызов с сервера идентификации (запрос на /signin-oidc).

Например, значения параметра состояния и PKCE не являются общими для всех экземпляров.

Комментарии:

1. В настоящее время я использую RsaKeyService, а не AddDeveloperSigningCredential, где два отдельных экземпляра имеют уникальный rsakey. файлы json. Просто для проверки я сделал оба этих rsakey. файлы json одинаковы, но сохраняется та же проблема. У меня действительно есть несколько экземпляров IdentityServer, по одному для каждого сервера, но оба они являются точно такими же файлами приложений, за исключением rsakey. файлы json. В этом случае, как вы думаете, мне все еще нужно настроить общий ключ защиты данных? Я тоже попытаюсь провести некоторые исследования для этого, спасибо!

2. Ключ подписи токена и Ключ защиты данных должны быть одинаковыми во всех экземплярах, если вы хотите, чтобы пользователи могли беспрепятственно перемещаться между машинами. Я вел блог об API защиты данных здесь edument.se/en/blog/post/…

3. Но, как я также сказал, экземпляр обработчика (AddOpenIDConnect…) также должен быть таким же, который обрабатывает весь «поток подписи». в противном случае у вас будут проблемы с состоянием/PKCE….

4. не стесняйтесь принять мой ответ, если он отвечает на ваши вопросы.

5. К сожалению, это, похоже, не решило мою проблему — я ввел следующее: строка sKeysPath = Путь. Объединить(Путь.GetDirectoryName(Сборка. GetExecutingAssembly(). Местоположение), «Ключи»); услуги. AddDataProtection() .SetApplicationName(«Мое приложение») .Файловая система PersistKeysToFileSystem(новый DirectoryInfo(sKeysPath)); Разместил автоматически сгенерированный ключ с одного сервера на противоположный сервер, но проблема сохраняется. Просто для уточнения, AddOpenIDConnect поступает из клиентского приложения.