IdentityServer4 撤销客户端的所有参考令牌,当前的除外
IdentityServer4 Revoke all reference tokens for a client, except the current one
我有一个受 IdentityServer4 引用令牌保护的单页应用程序。
我希望用户从多个登录 computers/devices。
在应用程序的设置区域,用户可以更改他们的密码。为此,他们必须输入当前密码以及新密码。
我还希望为用户提供“注销所有其他设备和计算机”的选项。
如果用户勾选此选项,我想使此客户端和此用户存在的任何其他参考令牌无效,但我不想使用户当前使用的参考令牌无效。
我只希望它注销 其他 设备和计算机。用户应该在他们正在使用的计算机上保持登录状态。
在我的一生中,我找不到使用 IdentityServer4 执行此操作的方法。我想我可以简单地 运行 删除 PersistedGrants table,但是我无法知道此 table 中的哪些持久授权是用户当前正在使用的。
请帮忙!
我终于解决了这个问题。确保您使用的是最新版本的 IdentityServer,因为它在 PersistedGrants table 上包含一个 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);
}
用户的其他令牌现已撤销。
但是,用户(在他们的另一个 computer/devices 上)可能仍然有一个身份验证 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;
}
}
我有一个受 IdentityServer4 引用令牌保护的单页应用程序。
我希望用户从多个登录 computers/devices。
在应用程序的设置区域,用户可以更改他们的密码。为此,他们必须输入当前密码以及新密码。
我还希望为用户提供“注销所有其他设备和计算机”的选项。
如果用户勾选此选项,我想使此客户端和此用户存在的任何其他参考令牌无效,但我不想使用户当前使用的参考令牌无效。
我只希望它注销 其他 设备和计算机。用户应该在他们正在使用的计算机上保持登录状态。
在我的一生中,我找不到使用 IdentityServer4 执行此操作的方法。我想我可以简单地 运行 删除 PersistedGrants table,但是我无法知道此 table 中的哪些持久授权是用户当前正在使用的。
请帮忙!
我终于解决了这个问题。确保您使用的是最新版本的 IdentityServer,因为它在 PersistedGrants table 上包含一个 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);
}
用户的其他令牌现已撤销。
但是,用户(在他们的另一个 computer/devices 上)可能仍然有一个身份验证 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;
}
}