簡體   English   中英

在ASP.net核心身份(UserManager和SignInManager)是否可以立即禁止用戶?

[英]In ASP.net core Identity (UserManager & SignInManager) is it possible to ban a user immediately?

我正在嘗試找到一種方法來為我正在開發的應用程序的管理員提供一種有效的方法來快速鎖定已經離開公司或被確定為行為的用戶,該用戶可以立即鎖定或使用該應用程序。

到目前為止看起來我可以;

//enable the account to be locked out
_userManager.SetLockoutEnabledAsync(ApplicationUser user, true);

//Set an arbitrary date way into the future to lock them out until I want to unlock them
_userManager.SetLockoutEndDateAsync(ApplicationUser user, "01/01/2060");

但如果用戶的cookie過期時間為30分鍾,則上述情況無法解決。 這意味着,如果用戶已經過身份驗證,並且在我用於使Cookie保持有效的默認時間內,則用戶可以繼續使用該應用。

是否有用戶管理器方法更改cookie被反彈的“檢查”? 我假設[Authorize]屬性標簽正在檢查cookie,而不是在表中未公開的Identity內。 想知道我如何更改“檢查”值以使它們與cookie會話不匹配?

您可以使用針對每個請求運行的一些中間件來執行此操作。 首先創建你的中間件類,如下所示:

public class UserDestroyerMiddleware
{
    private readonly RequestDelegate _next;

    public UserDestroyerMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext,
        UserManager<ApplicationUser> userManager,
        SignInManager<ApplicationUser> signInManager)
    {
        if (!string.IsNullOrEmpty(httpContext.User.Identity.Name))
        {
            var user = await userManager.FindByNameAsync(httpContext.User.Identity.Name);

            if (user.LockoutEnd > DateTimeOffset.Now)
            {
                //Log the user out and redirect back to homepage
                await signInManager.SignOutAsync();
                httpContext.Response.Redirect("/");
            }
        }
        await _next(httpContext);
    }
}

以及一個易於配置的擴展:

public static class UserDestroyerMiddlewareExtensions
{
    public static IApplicationBuilder UseUserDestroyer(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<UserDestroyerMiddleware>();
    }
}

現在,在Startup.csConfigure方法中,在設置Identity后添加以下行:

app.UseUserDestroyer();

現在,這個中間件應該在每個請求上運行,檢查用戶是否應該注銷。 您可能希望簡化此過程,方法是不在每個請求中訪問數據庫,而是使用某種最近刪除的用戶的緩存列表。

感謝@DavidG's aproach,我更多地考慮了這一點。

在幾乎每個控制器中,我必須讓用戶解決用戶是否屬於主機用戶組,特定租戶用戶組,和/或將用戶添加為EditedBy等字段中的編輯器,如果我是使用正在更新的對象。

這讓我想到了而不是;

var user = _userManager.GetUserByEmail(User.Identity.Name);

var hostId = user.HostId;

要么

var tenantId = user.TenantId;

要么

var EditedBy = user.Email;

我可以創建一個獲取用戶的類,還可以檢查用戶對象的狀態更改,例如“LockoutEnd> Today”或ClaimsHaveBeenUpdated。

因此,我提出了一種不同的方法來減輕每個請求上的兩個db調用。

控制器方法

var user = _userManager.GetUserByEmail(User.Identity.Name);

知識庫

public async Task<ApplicationUser> GetUserByEmailAsync(string email)
    {
       var user =  await _context.Users.FirstOrDefaultAsync(x=>x.Email.Equals(email));

        if(user.LockoutEnd > DateTimeOffset.Now )
        {
            await _signInManager.SignOutAsync();
        }
        if (user.CookieStateHasChanged)
        {
            user.CookieStateHasChanged = false;
            await _userManager.UpdateAsync(user);
            await _signInManager.RefreshSignInAsync(user);

        }
        return user;
    }

不幸的是,我已經在每個控制器GET方法上為用戶調用Db,以便在執行其他業務邏輯之前解析其租戶或主機用戶。 因此,通過將上面的額外代碼添加到我的repo中的GetUserByEmailAsync方法,我將DI添加到控制器構造函數中,我還可以通過刷新cookie或在用戶被鎖定時注銷用戶來處理用戶聲明更改。

請記住,如果角色發生變化,我將不得不更新user.CookieStateHasChange = true。

當用戶通過用戶界面“禁用”時,我正在更新用戶.LockoutEnd為10年+未來。

我認為一個相當簡單的方法是為此創建一個過濾器。 也許繼承Authorize屬性並檢查當前用戶的鎖定標志。 它也適用於以前版本的asp.net。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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