Блокировка MVC 5 Identity 2.0 не работает

Мне нужно навсегда заблокировать пользователя. Я не понимаю, почему этот код не работает.

Эта линия UserManager.IsLockedOut(user.Id); всегда возвращается false вместо true,

Может быть, необходимо поставить эту строку UserManager.UserLockoutEnabledByDefault = true; на этапе регистрации пользователя?

using (var _db = new ApplicationDbContext())
{
    UserStore<DALApplicationUser> UserStore = new UserStore<DALApplicationUser>(_db);
    UserManager<DALApplicationUser> UserManager = new UserManager<DALApplicationUser>(UserStore);
    UserManager.UserLockoutEnabledByDefault = true;
    DALApplicationUser user = _userService.GetUserByProfileId(id);
    bool a = UserManager.IsLockedOut(user.Id);
    UserManager.SetLockoutEnabled(user.Id, true);

    a = UserManager.IsLockedOut(user.Id);
    _db.SaveChanges();
}

3 ответа

Решение

Линия

UserManager.SetLockoutEnabled(user.Id, true);

не блокирует или разблокирует учетную запись. Этот метод используется для постоянного включения или отключения процесса блокировки для данной учетной записи пользователя. В настоящее время вы делаете вызов, который в основном настраивает эту учетную запись пользователя так, чтобы она была связана правилами блокировки учетной записи. Выполнение вызова со вторым параметром как false то есть:

UserManager.SetLockoutEnabled(user.Id, false);

позволит вам настроить учетную запись пользователя, которая освобождается от правил блокировки - это может быть полезно для учетной записи администратора.

Вот код для UserManager.IsLockedOutAsync:

/// <summary>
///     Returns true if the user is locked out
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public virtual async Task<bool> IsLockedOutAsync(TKey userId)
{
    ThrowIfDisposed();
    var store = GetUserLockoutStore();
    var user = await FindByIdAsync(userId).WithCurrentCulture();
    if (user == null)
    {
        throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.UserIdNotFound,
            userId));
    }
    if (!await store.GetLockoutEnabledAsync(user).WithCurrentCulture())
    {
        return false;
    }
    var lockoutTime = await store.GetLockoutEndDateAsync(user).WithCurrentCulture();
    return lockoutTime >= DateTimeOffset.UtcNow;
}

Как видите, для того, чтобы пользователь был классифицирован как заблокированный, блокировка должна быть включена, как указано выше, и пользователь должен иметь LockoutEndDateUtc значение, которое больше или равно текущей дате.

Таким образом, чтобы "навсегда" заблокировать учетную запись, вы можете сделать следующее:

using (var _db = new ApplicationDbContext())
{
    UserStore<DALApplicationUser> UserStore = new UserStore<DALApplicationUser>(_db);
    UserManager<DALApplicationUser> UserManager = new UserManager<DALApplicationUser>(UserStore);
    UserManager.UserLockoutEnabledByDefault = true;
    DALApplicationUser user = _userService.GetUserByProfileId(id);

    bool a = UserManager.IsLockedOut(user.Id);

    //user.LockoutEndDateUtc = DateTime.MaxValue; //.NET 4.5+
    user.LockoutEndDateUtc = new DateTime(9999, 12, 30);
    _db.SaveChanges();

    a = UserManager.IsLockedOut(user.Id);
}

Функция SetLockoutEnabled не блокирует пользователя, он включает функцию блокировки для пользователя

тебе нужно

UserManager.DefaultAccountLockoutTimeSpan = TimeSpan.FromHours(1); // lockout for 1 hour
UserManager.MaxFailedAccessAttemptsBeforeLockout = 5; // max fail attemps
UserManager.AccessFailedAsync(user.Id); // Register failed access

Он запишет ошибку и заблокирует пользователя, если блокировка включена и количество ошибок достигнуто.

Установите для значения shouldLockout значение true в действии входа в систему (по умолчанию оно равно false)

            // To enable password failures to trigger account lockout, change to shouldLockout: true
            var result = await SignInManager.PasswordSignInAsync(vm.Email, vm.Password, vm.RememberMe, shouldLockout: true);
Другие вопросы по тегам