一次使用后如何使两因素身份验证令牌过期

时间:2018-07-05 08:12:04

标签: asp.net-mvc-5 two-factor-authentication

我实现了两要素认证,但是通过遵循本教程

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

我要使代码在单次使用后失效。

现在,用户在到期时间(设置为5分钟)完成期间收到相同的代码。有没有办法使代码一次性使用?我在这个问题上找不到任何东西。

2 个答案:

答案 0 :(得分:1)

tutorial that you linked to中有一个注释,内容为:

  

2FA代码使用Time-based One-time Password Algorithm生成,并且代码有效期为6分钟。如果您花费超过六分钟的时间输入代码,则会收到一条无效的代码错误消息。

因此,使用此方法,您无法使代码在用户使用后失效。

此外,您可以保留一个已使用的代码存储,并在验证代码之前对其进行检查。您可以允许代码在6分钟(这是它们的自然到期时间)之后在该商店中过期,但是与此同时,请使用它们拒绝第二次身份验证。

或者,您可以选择避免使用TOTP方法,并在发送SMS或电子邮件之前针对用户存储随机代码。然后,您可以在用户对其进行身份验证时对照该代码进行检查,并在那时删除或使该代码无效。使用TOTP意味着您可以扩展此2FA以便也使用基于身份验证器应用程序的流进行身份验证,这比SMS或电子邮件更安全。

答案 1 :(得分:0)

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

相关问题