У меня есть устаревшее приложение, которое аутентифицирует пользователя, используя его в качестве Identity Server 2. Когда мы блокируем учетную запись пользователя после N неудачных попыток, обновив поля ниже:
- FailedPasswordAttemptCount
- IsLockedOut
- LastLockoutDate
- FailedPasswordAttemptWindowStart
Теперь мы переходим с Identity Server 2 на 4, и я понял, что в новой структуре таблицы [AspNetUsers] нет всех этих полей.Он содержит только три поля, как показано ниже:
- LockoutEnabled: Указывает, выбрал ли пользователь блокировку или нет.
- AccessFailedCount: Эти поля увеличиваются при каждой неудачной попытке входа в систему.
- LockoutEnd: Указывает время блокировки в минутах.
Как я уже говорил вам, в IdServ4[AspNetUsers] .AccessFailedCount будет увеличиваться при каждой неудачной попытке, а после MaxFailedAccessCount будет сбрасывать счетчик до 0 и устанавливать LockoutEnd с указанным интервалом времени (как настроено в файле запуска).
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Lockout.MaxFailedAccessAttempts = 3;
options.Lockout.DefaultLockoutTimeSpan = 15;
})
После всей этой исходной информации я перехожу к своей актуальной проблеме.
Предположим, пользователь зашел на нашу страницу входа в систему и сделал 2 неудачные попытки входа в систему, закрыл браузер и ушел на день, а затемзайдите на наш сайт несколько дней спустя и попытайтесь сделать еще одну неудачную попытку, теперь он пересек MaxFailedAccessCount и затем его аккаунт получитs заблокирован (код записан в библиотеке Identity Server), но согласно пользовательскому представлению он сделал только одну неудачную попытку.
Что я пытаюсь сделать:
Поскольку я не использую EntityFramework для взаимодействия с базой данных и написал для него собственные хранимые процедуры и сам реализовал все хранилища, чтобы я мог представитьПоле LastAccessFailedDate в таблице [AspNetUsers] и сравните его с текущей датой, когда пользователь предпринял неудачную попытку входа в систему, и если она меньше настроенного времени, я просто сброслю AccessFailedCount на 1 и существующее значение +1;
Оригинальный код:
public Task<int> IncrementAccessFailedCountAsync(TUser user, CancellationToken cancellationToken)
{
user.ThrowIfNull(nameof(user), cancellationToken);
return Task.FromResult(++user.AccessFailedCount);
}
Мой подход:
public Task<int> IncrementAccessFailedCountAsync(TUser user, CancellationToken cancellationToken)
{
user.ThrowIfNull(nameof(user), cancellationToken);
// Lets suppose _configuredResetTime configured to 60 minutes
If(user.LastAccessFailedDate > DateTime.Now.AddMinutes(_configuredResetTime))
{
user.AccessFailedCount += 1;
}
else
{
user.AccessFailedCount = 1;
}
user.LastAccessFailedDate = DateTime.Now;
return Task.FromResult(user.AccessFailedCount);
}
Примечание: Я не уверен, есть лиальтернатива, предоставленная библиотекой IdServ4, или мне нужно реализовать ее самостоятельно.
Ожидаемый результат:
Поэтому мне интересно, можем ли мы сбросить AccessFailedCount после настроенного периода времени, еслипользователь не активен на экране входа в систему, как мы делаем в IdServ2, используя поле [aspnet_Users] .FailedPasswordAttemptWindowStart.
Любые предложения приветствуются,Спасибо!