ASP.Net Identity 2.0 AccessFailedCount не увеличивается

#c# #asp.net #asp.net-mvc #authentication #asp.net-identity

#c# #asp.net #asp.net-mvc #аутентификация #asp.net-идентификатор

Вопрос:

Прошлой ночью я работал над новым проектом с использованием FormsAuthentication и настраивал тикет для включения токена безопасности, поэтому, если пользователь выходит из системы в одном браузере, он выходит из системы во всех них. При просмотре последней итерации ASP.net Идентичность, похоже, в нее уже встроена эта функциональность.

Я создал новое тестовое веб-приложение MVC 5 с включенными отдельными учетными записями. Регистрация и аутентификация работали прямо из коробки.

Однако я заметил, что неудачные попытки входа в систему не увеличивали поле AccessFailedCount в таблице AspNetUsers. И поскольку это не увеличивалось, я мог попробовать столько неудачных попыток входа в систему, сколько хотел, не блокируя учетную запись.

Как мне включить функцию AccessFailedCount и блокировки на ASP.net Идентичность 2.0?

Ответ №1:

Вы должны обработать это вручную. CheckPassword Метод вызывает PasswordHasher.VerifyHashedPassword метод для проверки пароля, но он не обновляет счетчик ошибок доступа, если предоставленный пароль не соответствует существующему.

Вот пример метода аутентификации, который поддерживает блокировку:

 UserManager<User> userManager = new UserManager<User>(new UserStore());

if (userManager.SupportsUserLockout amp;amp; userManager.IsLockedOut(userId))
    return;

var user = userManager.FindById(userId);
if (userManager.CheckPassword(user, password))
{
    if (userManager.SupportsUserLockout amp;amp; userManager.GetAccessFailedCount(userId) > 0)
    {
        userManager.ResetAccessFailedCount(userId);
    }

    // Authenticate user
}
else
{
    if (userManager.SupportsUserLockout amp;amp; userManager.GetLockoutEnabled(userId))
    {
        userManager.AccessFailed(userId);
    }
}
  

Комментарии:

1. Спасибо, я надеялся, что это не ручной процесс. Из-за всей разбросанной конфигурации, непрочных абстракций и прочего, что вам приходится реализовывать вручную, мне трудно понять значение ASP.net Идентификация через старую систему аутентификации FormsAuthentication (если вы не используете внешних поставщиков аутентификации).

2. SignInManager в версии 2.1 — это то, что обеспечит API PasswordSignIn более высокого уровня, который скрывает большую сложность, связанную с блокировкой / двумя факторами и т. Д.

3. конечно же, как сказал @HaoKung, в версии v2.2.1, в которой я только что начал новый проект, в этой строке var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false); просто измените значение false на true , для тех, кто приземляется здесь, как я, и нуждается в этом.

4. Что делать, если вызов AccessFailed также не повторяет AccessFailedCount и SupportsUserLockout имеет значение true?

5. Да, у нас была собственная реализация для asp.net 2.X аутентификация и авторизация для устранения значительных недостатков аутентификации веб-форм по умолчанию… я очень удивлен, обнаружив так много проблем с asp.net идентичность так много лет спустя. Разве MS не может найти достойных разработчиков?

Ответ №2:

Существует также PasswordSignInAsync, который принимает аргумент «shouldLockout». Установка этого значения в true приведет к автоматическому увеличению неудачных попыток входа в систему

 var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: true);
  

Комментарии:

1. Все равно может показаться, что вам нужно вызвать ResetAccessFailedCountAsync(), если пользователь успешно вошел в систему. Понятия не имею, почему этого кода нет в шаблоне проекта по умолчанию.

2. Обратите внимание, что AccessFailed сбрасывается 0 в конце цикла «сбой». После достижения максимального количества попыток выполняется AccessFailed сброс 0 и LockoutEndDateUtc устанавливается снова. У вас есть доступ только к количеству неудачных попыток в каждом fail цикле.

3. @JoelB Теперь это поведение по умолчанию (по крайней мере, в 2.2).

Ответ №3:

Для .NET Core 2.1 блокировка Shouldl теперь называется lockoutOnFailure

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

 var result = await SignInManager.PasswordSignInAsync(loginModel.Email, loginModel.Password, loginModel.RememberMe, lockoutOnFailure: true);
  

Это также приведет к сбросу неудачных попыток входа в систему после успешного входа пользователя в систему.