[英]Force logout in ASP.NET MVC Core
I'm using ASP.Net MVC Core where I have the following code where it is a daily task that sets users as "Expired" if their subscription is over.我正在使用 ASP.Net MVC Core,其中我有以下代码,这是一项日常任务,如果用户的订阅结束,则将其设置为“已过期”。 But how can I also check and force them to logout if they are currently logged in?
但是,如果他们当前已登录,我还如何检查并强制他们注销?
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();
}
}
Any help is highly appreciated.非常感谢任何帮助。
You can add a SecurityStamp
property of type GUID
to users model and set SecurityStamp
to cookie
or jwt
token.您可以向用户 model 添加
GUID
类型的SecurityStamp
属性,并将SecurityStamp
设置为cookie
或jwt
令牌。
then when a user login, you must change the SecurityStamp
value to a new value and save SecurityStamp
to cookie and any time user send a request to application you must check SecurityStamp
saved in cookie with SecurityStamp
of users in database.然后当用户登录时,您必须将
SecurityStamp
值更改为新值并将SecurityStamp
保存到 cookie,并且任何时候用户向应用程序发送请求时,您必须检查保存在 cookie 中的SecurityStamp
以及数据库中用户的SecurityStamp
。 and if these properties wasn't equal togeter you must reject user and set sign out user.如果这些属性不等于 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);
}
}
In startup class pass ValidateAsync
method to OnValidatePrincipal
and set ValidationInterval
to zero.在启动 class 中,将
ValidateAsync
方法传递给OnValidatePrincipal
并将ValidationInterval
设置为零。
services.ConfigureApplicationCookie(options =>
{
//
options.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = ValidateAsync
};
}).Configure<SecurityStampValidatorOptions>(options =>
{
options.ValidationInterval = TimeSpan.Zero;
});
finally in your method just update SecurityStamp
value like this:最后,在您的方法中,只需像这样更新
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.