#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 поступает из клиентского приложения.