Как настроить IdentityServer4 для предоставления маркера обновления, только если отметка безопасности пользователя не изменилась?
У меня есть два проекта веб-приложений ASP.NET Core 2.0, давайте назовем их A и B. Роль A - выступать в качестве поставщика OpenID Connect (для этого он использует IdentityServer4); пользователи B входят через A, используя внешний процесс входа в систему. Доступ к базе данных пользователей осуществляется A, а не B. B настроен на использование потока "CodeAndClientCredentials".
Я хотел, чтобы B перепроверил с A, когда прошло определенное время с момента выдачи cookie - идея состояла в том, что пользователь сможет оставаться в системе, но через некоторое время автоматически выйдет из системы, если отметка о его безопасности изменения.
Я нашел этот полезный пример проекта, который демонстрирует, как токен доступа и токен обновления могут автоматически обновляться каждый раз, когда пользователь посещает страницу. Однако после реализации метода, показанного в этом примере проекта, я обнаружил, что, если я инициирую изменение штампа безопасности пользователя после входа в систему, IdentityServer4 все равно с радостью выдаст новые токены доступа и обновит токены.
Я бы хотел, чтобы IdentityServer4 отказался выдать новый токен доступа, если отметка безопасности пользователя изменилась. Я хотел бы понять, почему это не поведение по умолчанию; я неправильно понимаю, какие сценарии обновления маркеров предназначены для включения? Это тот случай, когда IdentityServer4 не имеет средств, чтобы определить, изменился ли штамп безопасности? Существуют ли какие-либо средства настройки IdentityServer4 для изменения этого поведения?
В качестве альтернативы, если есть стандартный способ достижения того, что я пытаюсь сделать, используя другие средства, я хотел бы знать, что это такое. Я могу придумать способы сделать это сам - например, B мог бы проверить с помощью API, изменилась ли отметка безопасности для вошедшего в систему пользователя, и отклонить принципал, если так, - но я не уверен, что гораздо более простой Существует решение, которое я пропускаю.
Для справки, конфигурация B как клиента A:
new Client
{
ClientId = "B",
ClientSecrets = {new Secret("hashed secret for B")},
AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
AllowedScopes = {"openid", "profile", ...},
RedirectUris = {$"https://localhost:44333/Account/oidc-callback"},
RequireConsent = false,
AccessTokenLifetime = 60,
AllowOfflineAccess = true,
// UpdateAccessTokenClaimsOnRefresh = true, // Have tried setting this - no difference
}
Конфигурация IdentityServer4 из Startup.cs:
var identityServerBuilder = services
.AddIdentityServer(
options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = isDevelopmentEnvironment;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = isDevelopmentEnvironment;
}
)
.AddInMemoryIdentityResources(Resources.GetIdentityResources())
.AddInMemoryApiResources(Resources.GetApiResources())
.AddInMemoryClients(Clients.GetClients(configuration))
.AddOperationalStore(...)
.AddAspNetIdentity<IdentityServiceUser>()
.AddProfileService<IdentityUserProfileService>();