On ASP.net CORE 3, when a user logout, I would like to invalidate all the cookies that exist on different devices. The user might have logged in from several different browsers, and the user has the option to use "Remember me" that lasts 30 days. My understanding to solve this problem so far:
- Use a securityStamp (a GUID) that I store in the database at the user level
- Add this securityStamp in the Claims at login
- When logout => change the securityStamp in the database
- When http request arrives on a method of controller with [Authorize] attribute, check if the securityStamp match the one stored in the database. If not, redirect to login page.
My question is about point 4) where and how write this securityStamp check in the ASP.net CORE framework and redirect to login page ?
Here is my code at login time
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);
}
UPDATE: I have my own user table, I don't use entityFramework and the whole built-in Identity management.
CodePudding user response:
You can use the SecurityStamp
Property and the SecurityStampValidatorOptions.ValidationInterval
Property to make the logout user's cookie invalid.
1.Register ValidationInterval
in ConfigureServices
services.Configure<SecurityStampValidatorOptions>(options =>
{
options.ValidationInterval = TimeSpan.FromSeconds(1);//set your time
});
2.Add userManager.UpdateSecurityStampAsync()
in your Logout like below
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");
}
Result: