【问题标题】:IdentityServer4 Revoke all reference tokens for a client, except the current oneIdentityServer4 撤销客户端的所有引用令牌,当前的除外
【发布时间】:2021-06-28 21:52:18
【问题描述】:

我有一个受 IdentityServer4 引用令牌保护的单页应用程序。

我希望用户从多台计算机/设备登录。

在应用程序的设置区域,用户可以更改他们的密码。为此,他们必须输入当前密码以及新密码。

我还希望为用户提供“注销所有其他设备和计算机”的选项。

如果用户勾选此选项,我想使此客户端和此用户存在的任何其他引用令牌无效,但我不想使用户当前使用的引用令牌无效。

我只希望它退出 其他 设备和计算机。用户应该在他们正在使用的计算机上保持登录状态。

在我的一生中,我找不到使用 IdentityServer4 的方法。我在想我可以简单地在 PersistedGrants 表上运行删除,但是我无法知道该表中的哪个持久授权是用户当前正在使用的。

请帮忙!

【问题讨论】:

    标签: asp.net-core identityserver4


    【解决方案1】:

    我终于能够解决这个问题。确保您使用的是最新版本的 IdentityServer,因为它在 PersistedGrants 表中包含一个 session_id 列。有了这个,解决方案就很清楚了。

    当用户更改密码时:

            if (model.EndSessions)
            {
    
                var currentSessionId = User.FindFirst(JwtClaimTypes.SessionId).Value;
    
                foreach (var grant in db.PersistedGrants.Where(pg => pg.ClientId == "the-client-name" && pg.SubjectId == user.Id.ToString() && pg.SessionId != currentSessionId).ToList())
                {
                    db.PersistedGrants.Remove(grant);
                }
    
                db.SaveChanges();
    
                await userManager.UpdateSecurityStampAsync(user);
    
            }
    

    该用户的其他令牌现已被撤销。

    但是,用户(在他们的其他计算机/设备上)可能仍然有一个身份验证 cookie,因此如果他们要访问授权端点,他们将获得一个新令牌,而无需再次登录。

    为了防止这种情况,我们拦截了带有CustomProfileService 的新令牌的请求,就像这样 -

        public override async Task IsActiveAsync(IsActiveContext context)
        {
    
            //only run check for cookie authentication
            if (context.Subject.Identity.AuthenticationType == IdentityConstants.ApplicationScheme)
            {
    
                var validationResponse = await signInManager.ValidateSecurityStampAsync(context.Subject);
    
                if (validationResponse == null)
                {
                    context.IsActive = false;
                    return;
                }
    
                var user = await userManager.GetUserAsync(context.Subject);
    
                context.IsActive = user.IsActive;
    
            }
    
    
        }
    

    【讨论】:

    • IPersistedGrantService 通过RemoveAllGrantsAsync(user.Id.ToString()) 方法支持此功能。
    猜你喜欢
    • 2018-06-02
    • 1970-01-01
    • 2017-06-15
    • 1970-01-01
    • 2021-07-05
    • 2021-11-14
    • 2020-02-20
    • 1970-01-01
    • 2020-06-02
    相关资源
    最近更新 更多