Как автоматически сбросить AccessFailedCount по истечении указанного времени в Identity Server 4 - PullRequest
0 голосов
/ 04 мая 2019

У меня есть устаревшее приложение, которое аутентифицирует пользователя, используя его в качестве 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.

Любые предложения приветствуются,Спасибо!

...