IdentityServer4强制注销

时间:2020-06-10 22:31:01

标签: identityserver4

如何通过不同用户的会话为用户外部触发(完全)注销?

例如,“管理员”登录并注销用户“ JohnDoe”(来自IdentityServer和所有客户端)。

IdentityServer支持在用户注销时(通过前通道或后通道)通知客户端。太好了,但是如何从用户会话之外开始滚动呢?

1 个答案:

答案 0 :(得分:1)

令牌的问题是您无法删除令牌,必须通过从商店中将其删除来撤消令牌,以使其不再可用。实际上,使用反向通道注销会遇到相同的问题。您无法直接删除Cookie,但客户端可以在下一个请求时拒绝它。

对于用户会话,反向通道注销可以从IdentityServer网站上可用的cookie中读取会话信息。但是,管理员无权访问此信息,因此您需要存储用户会话服务器端。

这可以在客户端或IdentityServer上。我将在客户端实现一个会话管理器,因为是客户端验证cookie并可以删除cookie(在下一个请求时)。

这允许IdentityServer执行正常的反向通道注销,并将其留给客户端以从LogoutCallback上的会话管理器中删除一个或所有条目。这样,您可以为不同的客户实施不同的策略。

如果会话不可用,客户端可以向会话管理器咨询cookie验证并拒绝访问。像这样:

public class CookieEventHandler : CookieAuthenticationEvents
{
    private SessionManager _sessionManager { get; }

    public CookieEventHandler(SessionManager sessionManager)
    {
        _sessionManager = sessionManager;
    }

    public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
    {
        if (context.Principal.Identity.IsAuthenticated)
        {
            var sub = context.Principal.FindFirst("sub")?.Value;

            if (!_sessionManager.HasSession(sub))
            {
                context.RejectPrincipal();
                await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            }
        }
    }
}

在启动时:

services
    .AddAuthentication(options =>
    {
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";
    })
    .AddCookie("Cookies", options =>
    {
        options.EventsType = typeof(CookieEventHandler);
    })