簡體   English   中英

在 ASP.NET MVC Core 中強制注銷

[英]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設置為cookiejwt令牌。

然后當用戶登錄時,您必須將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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM