Как сделать так, чтобы срок действия двухфакторного токена аутентификации истек после однократного использования

Я реализовал двухфакторную аутентификацию, но, следуя этому руководству

https://docs.microsoft.com/en-us/aspnet/identity/overview/features-api/two-factor-authentication-using-sms-and-email-with-aspnet-identity

Я хочу, чтобы срок действия кода истек после однократного использования.

Прямо сейчас пользователь получает тот же код в течение времени истечения (которое установлено на 5 минут). Есть ли способ сделать код одноразовым? Я не мог ничего найти на эту тему.

1 ответ

В учебном пособии есть ссылка на следующее:

Коды 2FA генерируются с использованием алгоритма одноразового пароля на основе времени, и коды действительны в течение шести минут. Если на ввод кода у вас уходит более шести минут, вы получите сообщение об ошибке "Неверный код".

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

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

Кроме того, вы можете отказаться от метода TOTP и сгенерировать случайный код, который вы сохраняете для своего пользователя перед отправкой SMS или электронной почты. Затем вы можете проверить этот код, когда пользователь аутентифицируется с ним, и удалить или аннулировать код в этой точке. Использование TOTP означает, что вы можете расширить этот 2FA для использования потока аутентификации на основе приложения аутентификации, который более безопасен, чем SMS или электронная почта.

AspNetIdentity не делает автоматически недействительными использованные коды второго фактора, код всегда действителен в течение шести минут, но для этого есть обходной путь.

Один из входов в генератор токенов - это SecurityStamp, который хранится как часть учетной записи пользователя. Поставщики токенов, расширяющиеTotpSecurityStampBasedTokenProvider, как например EmailTokenProvider, будут использовать штамп безопасности при создании и проверке кода второго фактора.

Таким образом, вы можете аннулировать все выпущенные токены, изменив штамп безопасности, позвонив UserManager.UpdateSecurityStampAsync(userId) после успешной двухфакторной аутентификации.

в ApplicationSignInManager класс, вы можете переопределить TwoFactorSignInAsyncи позвоните туда: (Примечание: это взято из AspNetIdentity, если вы используете другой пакет, обязательно возьмитеTwoFactorSignInAsync вместо этого и соответствующим образом измените его.)

public override async Task<SignInStatus> TwoFactorSignInAsync(string provider, string code, bool isPersistent, bool rememberBrowser)
{
    var userId = await GetVerifiedUserIdAsync().WithCurrentCulture();
    if (userId == null)
    {
        return SignInStatus.Failure;
    }
    var user = await UserManager.FindByIdAsync(userId).WithCurrentCulture();
    if (user == null)
    {
        return SignInStatus.Failure;
    }
    if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture())
    {
        return SignInStatus.LockedOut;
    }
    if (await UserManager.VerifyTwoFactorTokenAsync(user.Id, provider, code).WithCurrentCulture())
    {
        // When token is verified correctly, clear the access failed count used for lockout
        await UserManager.ResetAccessFailedCountAsync(user.Id).WithCurrentCulture();

        // Update the security stamp in order to invalidate all issued two factor tokens.
        await UserManager.UpdateSecurityStampAsync(user.Id);

        await SignInAsync(user, isPersistent, rememberBrowser).WithCurrentCulture();
        return SignInStatus.Success;
    }
    // If the token is incorrect, record the failure which also may cause the user to be locked out
    await UserManager.AccessFailedAsync(user.Id).WithCurrentCulture();
    return SignInStatus.Failure;
}

Если вы хотите, чтобы действительным был только последний выданный код, вам следует позвонить в UpdateSecurityStampAsync также до создания любого нового кода.

Другие вопросы по тегам