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



我正在尝试找到一种方法来提供我正在开发的应用程序的管理员,以快速封锁已离开公司或已被确定为以一种值得立即锁定或使用应用程序的方式行事。

到目前为止看起来我可以;

//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");

但是,如果用户有30分钟到期时间的cookie,则无法解决。意思是,如果用户已经进行了身份验证,并且可以继续使用该应用程序,并且在我使用的默认时间内cookie保持有效。

是否存在更改cookie反弹的"检查"的用户管理方法?我假设[授权]属性标签正在检查表中未暴露的身份中的事物。想知道我如何更改"检查"值,以使它们不匹配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.cs中的Configure方法中,在设置Identity之后添加此行:

app.UseUserDestroyer();

现在,此中间件应在每个请求上运行,检查用户是否应登录。您可能需要通过使其在每个请求上都击中数据库来简化此过程,而是使用某种最近删除的用户的缓存列表。

我不得不再考虑一下 @davidg的掠夺。

在几乎每个控制器中,我都必须获取用户以解决用户属于主机用户组,特定租户用户组,并且/或在诸如编辑中的字段中添加用户作为编辑器,例如我正在使用正在更新的对象。

这让我想到,而不是

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

var tenantId = user.TenantId;

var EditedBy = user.Email;

我可以创建一个可以获取用户的类,但还可以检查用户对象是否为" lockoutend> today> today"或索赔saimeshavebeenupdupted进行检查。

因此,这是我提出的一种不同的方法来减轻每个请求的两个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;
    }

不幸的是,我已经在执行其他业务逻辑之前,我已经在每个控制器的租户或主机用户中为用户呼叫DB,以解决该方法以解决。因此,通过将上面的额外代码添加到我的存储库中的getuserbyemailasync方法中,我还可以将用户索赔更改来处理cookie或在用户锁定的情况下签名。

> 。

请记住,如果角色更改,我必须更新user.cookiestatehaschange = true。

以及当用户通过UI"禁用"用户时,我将用户更新为10年 在路上。

我认为一种相当简单的方法是为此创建过滤器。也许继承Authorize属性并检查当前用户的锁定标志。它也适用于ASP.NET的先前版本。

最新更新