我终于能够解决这个问题。确保您使用的是最新版本的 IdentityServer,因为它session_id在 PersistedGrants 表中包含一列。有了这个,解决方案就很清楚了。
当用户更改密码时:
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,因此如果他们要访问授权端点,他们将获得一个新令牌,而无需再次登录。
为了防止这种情况发生,我们用 a 拦截对新令牌的请求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;
}
}