Как настроить 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>();

0 ответов

Другие вопросы по тегам