[英]Force logout in ASP.NET MVC Core
我正在使用 ASP.Net MVC Core,其中我有以下代碼,這是一項日常任務,如果用戶的訂閱結束,則將其設置為“已過期”。 但是,如果他們當前已登錄,我還如何檢查並強制他們注銷?
public interface IExpirationJob
{
Task SetExpired();
}
public class ExpirationJob : IExpirationJob
{
private readonly ApplicationDbContext _db;
private readonly IEmailSender _emailSender;
public ExpirationJob(ApplicationDbContext db, IEmailSender emailSender)
{
_db = db;
_emailSender = emailSender;
}
public async Task SetExpired()
{
foreach(var item in _db.Institution)
{
if (item.SubscriptionEndDate != null)
{
if (item.SubscriptionEndDate == DateTime.Today)
{
item.Status = SD.StatusExpired;
//Here I want to check if the user is logged in, then force logout should be done.
}
}
}
await _db.SaveChangesAsync();
}
}
非常感謝任何幫助。
您可以向用戶 model 添加GUID
類型的SecurityStamp
屬性,並將SecurityStamp
設置為cookie
或jwt
令牌。
然后當用戶登錄時,您必須將SecurityStamp
值更改為新值並將SecurityStamp
保存到 cookie,並且任何時候用戶向應用程序發送請求時,您必須檢查保存在 cookie 中的SecurityStamp
以及數據庫中用戶的SecurityStamp
。 如果這些屬性不等於 geter,您必須拒絕用戶並設置注銷用戶。
public static async Task ValidateAsync(CookieValidatePrincipalContext context)
{
context = context ?? throw new ArgumentNullException(nameof(context));
var claimsIdentity = context.Principal.Identity as ClaimsIdentity;
if(claimsIdentity?.Claims == null || !claimsIdentity.Claims.Any())
{
await RejectPrincipal();
return;
}
UserManager<IdentityUser> userManager = context.HttpContext.RequestServices.GetRequiredService<UserManager<IdentityUser>>();
var user = await userManager.FindByNameAsync(context.Principal.FindFirstValue(ClaimTypes.NameIdentifier));
if (user == null || user.SecurityStamp != context.Principal.FindFirst(new ClaimsIdentityOptions().SecurityStampClaimType)?.Value)
{
await RejectPrincipal();
return;
}
async Task RejectPrincipal()
{
context.RejectPrincipal();
await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
}
在啟動 class 中,將ValidateAsync
方法傳遞給OnValidatePrincipal
並將ValidationInterval
設置為零。
services.ConfigureApplicationCookie(options =>
{
//
options.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = ValidateAsync
};
}).Configure<SecurityStampValidatorOptions>(options =>
{
options.ValidationInterval = TimeSpan.Zero;
});
最后,在您的方法中,只需像這樣更新SecurityStamp
值:
public async Task SetExpired()
{
foreach(var item in _db.Institution)
{
if (item.SubscriptionEndDate != null)
{
if (item.SubscriptionEndDate == DateTime.Today)
{
item.Status = SD.StatusExpired;
//Here I want to check if the user is logged in, then force logout should be done.
Guid securityStamp = Guid.NewGuid();
item.SecurityStamp = securityStamp;
}
}
}
await _db.SaveChangesAsync();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.