ASP.net身份禁用用户

Lor*_*rez 29 asp.net-mvc-5 asp.net-identity

在MVC 5中使用新的ASP.net标识,我们如何禁止用户登录?我不想删除它们,也许只是在一段时间内禁用它们的帐户.

有没有人对此有任何想法,因为我没有在ASPNetUsers表上看到状态列或任何内容.

小智 36

await userManager.SetLockoutEnabledAsync(applicationUser.Id, true);
await userManager.SetLockoutEndDateAsync(DateTime.Today.AddYears(10));
Run Code Online (Sandbox Code Playgroud)

  • 使用await userManager.SetLockoutEndDateAsync(applicationUser.Id,DateTimeOffset.MaxValue); (7认同)

Chr*_*ley 9

更新:正如CountZero指出的那样,如果您使用的是v2.1 +,那么在尝试下面的解决方案之前,您应该尝试使用他们首先添加的锁定功能.有关完整示例,请参阅他们的博客文章:http://blogs.msdn.com/b/webdev/archive/2014/08/05/announcing-rtm-of-asp-net-identity-2-1-0.aspx


版本2.0具有可用于锁定用户的IUserLockoutStore接口,但缺点是除了UserManager类公开的传递方法之外,没有OOB功能可以实际利用它.例如,如果它实际上将锁定计数增加为标准用户名/密码验证过程的一部分,那将是很好的.但是,实现自己是相当微不足道的.

步骤1:创建实现IUserLockoutStore的自定义用户存储.

// I'm specifying the TKey generic param here since we use int's for our DB keys
// you may need to customize this for your environment
public class MyUserStore : IUserLockoutStore<MyUser, int>
{
    // IUserStore implementation here

    public Task<DateTimeOffset> GetLockoutEndDateAsync(MyUser user)
    {
        //..
    }

    public Task SetLockoutEndDateAsync(MyUser user, DateTimeOffset lockoutEnd)
    {
        //..
    }

    public Task<int> IncrementAccessFailedCountAsync(MyUser user)
    {
        //..
    }

    public Task ResetAccessFailedCountAsync(MyUser user)
    {
        //..
    }

    public Task<int> GetAccessFailedCountAsync(MyUser user)
    {
        //..
    }

    public Task<bool> GetLockoutEnabledAsync(MyUser user)
    {
        //..
    }

    public Task SetLockoutEnabledAsync(MyUser user, bool enabled)
    {
        //..
    }
}
Run Code Online (Sandbox Code Playgroud)

步骤#2:在登录/注销操作中使用以下类代替UserManager,将其传递给自定义用户存储的实例.

public class LockingUserManager<TUser, TKey> : UserManager<TUser, TKey>
    where TUser : class, IUser<TKey> 
    where TKey : IEquatable<TKey> 
{
    private readonly IUserLockoutStore<TUser, TKey> _userLockoutStore;

    public LockingUserManager(IUserLockoutStore<TUser, TKey> store)
        : base(store)
    {
        if (store == null) throw new ArgumentNullException("store");

        _userLockoutStore = store;
    }

    public override async Task<TUser> FindAsync(string userName, string password)
    {
        var user = await FindByNameAsync(userName);

        if (user == null) return null;

        var isUserLockedOut = await GetLockoutEnabled(user);

        if (isUserLockedOut) return user;

        var isPasswordValid = await CheckPasswordAsync(user, password);

        if (isPasswordValid)
        {
            await _userLockoutStore.ResetAccessFailedCountAsync(user);
        }
        else
        {
            await IncrementAccessFailedCount(user);

            user = null;
        }

        return user;
    }

    private async Task<bool> GetLockoutEnabled(TUser user)
    {
        var isLockoutEnabled = await _userLockoutStore.GetLockoutEnabledAsync(user);

        if (isLockoutEnabled == false) return false;

        var shouldRemoveLockout = DateTime.Now >= await _userLockoutStore.GetLockoutEndDateAsync(user);

        if (shouldRemoveLockout)
        {
            await _userLockoutStore.ResetAccessFailedCountAsync(user);

            await _userLockoutStore.SetLockoutEnabledAsync(user, false);

            return false;
        }

        return true;
    }

    private async Task IncrementAccessFailedCount(TUser user)
    {
        var accessFailedCount = await _userLockoutStore.IncrementAccessFailedCountAsync(user);

        var shouldLockoutUser = accessFailedCount > MaxFailedAccessAttemptsBeforeLockout;

        if (shouldLockoutUser)
        {
            await _userLockoutStore.SetLockoutEnabledAsync(user, true);

            var lockoutEndDate = new DateTimeOffset(DateTime.Now + DefaultAccountLockoutTimeSpan);

            await _userLockoutStore.SetLockoutEndDateAsync(user, lockoutEndDate);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

示例:

    [AllowAnonymous]
    [HttpPost]
    public async Task<ActionResult> Login(string userName, string password)
    {
        var userManager = new LockingUserManager<MyUser, int>(new MyUserStore())
        {
            DefaultAccountLockoutTimeSpan = /* get from appSettings */,
            MaxFailedAccessAttemptsBeforeLockout = /* get from appSettings */
        };

        var user = await userManager.FindAsync(userName, password);

        if (user == null)
        {
            // bad username or password; take appropriate action
        }

        if (await _userManager.GetLockoutEnabledAsync(user.Id))
        {
            // user is locked out; take appropriate action
        }

        // username and password are good
        // mark user as authenticated and redirect to post-login landing page
    }
Run Code Online (Sandbox Code Playgroud)

如果您想手动锁定某人,您可以设置您正在检查的任何标志MyUserStore.GetLockoutEnabledAsync().

  • GetLockoutEnabledAsync不检查用户是否被锁定.顾名思义,它会检查锁定是否已启用. (3认同)