使 ASP.net 核心 3 中的所有身份验证 cookie 失效

Invalidate all authentication cookies in ASP.net CORE 3

在 ASP.net CORE 3 上,当用户注销时,我想使不同设备上存在的所有 cookie 失效。用户可能已从多个不同的浏览器登录,并且用户可以选择使用持续 30 天的“记住我”。 到目前为止我对解决这个问题的理解:

  1. 使用我在用户级别存储在数据库中的 securityStamp(GUID)
  2. 在登录时的声明中添加此安全戳
  3. 注销时 => 更改数据库中的 securityStamp
  4. 当http 请求到达具有[Authorize] 属性的控制器方法时,检查securityStamp 是否与数据库中存储的相匹配。如果没有,重定向到登录页面。

我的问题是关于第 4 点)在哪里以及如何在 ASP.net CORE 框架中编写此 securityStamp 检查并重定向到登录页面?

这是我登录时的代码

string securityStamp = Guid.NewGuid().ToString();
saveSecurityStampInDB(securityStamp, user.Id);
var userClaims = new List<Claim>()
                        {
                            new Claim("id", user.Id.ToString()),
                            new Claim("securityStamp", securityStamp),
                            new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string")
                         };
    
    var grantMyIdentity = new ClaimsIdentity(userClaims, "User Identity");
    var userPrincipal = new ClaimsPrincipal(new[] { grantMyIdentity });
    if (rememberMe.HasValue && rememberMe.Value)
    {
           await HttpContext.SignInAsync(userPrincipal, new AuthenticationProperties
           {
                    IsPersistent = true,
                    ExpiresUtc = DateTime.UtcNow.AddMonths(1)
           });
    }
    else
    {
       await HttpContext.SignInAsync(userPrincipal);
    }

更新: 我有自己的用户 table,我不使用 entityFramework 和整个内置身份管理。

您可以使用 SecurityStamp 属性 和 SecurityStampValidatorOptions.ValidationInterval 属性 使注销用户的 cookie 无效。

1.Register ValidationInterval 在 ConfigureServices

services.Configure<SecurityStampValidatorOptions>(options =>
            {
                options.ValidationInterval = TimeSpan.FromSeconds(1);//set your time
                
            });

2.Add userManager.UpdateSecurityStampAsync()在您的注销中,如下所示

public async Task<IActionResult> Logout()
        {
            var userid = userManager.GetUserId(User);
            var user = await userManager.FindByIdAsync(userid);
            await userManager.UpdateSecurityStampAsync(user);
            await signInManager.SignOutAsync();
 
            return RedirectToAction("Index", "Home");
        }

结果: