我正在尝试使用电子邮件中发送的密码添加双因素身份验证。用户只有在用户上次完成2FA步骤30天后才需要执行2FA步骤。
Project的技术是ASP.NET MVC 5,它使用EntityFramework 6和Microsoft.AspNet.Identity包的NuGet包2.2.2版(。Core,.EntityFramework,.Owin)。
我一直在遵循本教程中的建议,但将其集成到我公司现有的解决方案中:https://docs.microsoft.com/en-us/aspnet/identity/overview/features-api/two-factor-authentication-using-sms-and-email-with-aspnet-identity
我的问题
使用PasswordSignIn时,SignInManager永远不会返回RequiresVerification我假设我应该期望这个登录状态,当数据库中的“TwoFactorEnabled”标志为每个用户设置为true时。如果我只希望用户每两周进行一次2FA验证,我不确定是否应该使用此功能,因为我的印象是每次都要求用户完成此操作。或者我应该使用设置在用户上的时间戳来确定是否需要重新启用“TwoFactorEnabled”标志?
我无法检索验证用户的ID,在验证代码时我认为在执行正常的PasswordSignIn后,服务器将能够检索用户的ID,例如在验证输入的密码是否正确时:
[HttpPost]
[AllowAnonymous]
public async Task<ActionResult> VerifyCode(string pin)
{
string userId = await SignInManager.GetVerifiedUserIdAsync().WithCurrentCulture();
if (userId == null || String.IsNullOrEmpty(pin))
{
return View("Error");
}
var user = await UserManager.FindByIdAsync(userId);
if (await UserManager.VerifyTwoFactorTokenAsync(user.Id, "EmailCode", pin))
{
await SignInManager.SignInAsync(user, false, false);
return RedirectToAction("Index", "Dashboards");
}
else
{
ModelState.AddModelError("", "Invalid code");
}
return View();
}
这有点令人困惑,因为大多数教程都非常陈旧,并使用我从未见过的AuthenticationManager。
如果用户已经“使用用户名和密码成功登录”,如何阻止用户从验证屏幕直接跳到其他页面?此时他们是否无法绕过授权属性?
什么工作我可以让UserManager发送带有令牌(密码)的电子邮件,如果我输入正确的用户ID,它将被成功验证
我做了什么我有标准/默认的身份设置,所以我们使用的标准配置几乎与新的MVC 5项目一起使用。
Startup.Auth:
// Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(10));
// Enables the application to remember the second login verification factor such as phone or email.
// Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
// This is similar to the RememberMe option when you log in.
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
ApplicationUserManager中的2FA提供程序设置:
manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser>
{
Subject = "Security Code",
BodyFormat = "Your security code is {0}"
});
manager.EmailService = new EmailService();
//manager.SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
非常感谢您提前寻求帮助。
我想我可能已经弄明白问题是什么了。 UserManager为GetValidTwoFactorProvidersAsync返回0。当用户未确认电子邮件时,似乎会发生这种情况。我为用户确认了设置电子邮件,现在返回RequiresVerification。
返回RequiresVerification时,似乎用户未完全登录,但我仍然可以使用SignInManager的GetVerifiedUserId方法在后续代码验证调用中获取用户ID。
所以现在,当用户登录时,在执行密码登录之前,我只需执行检查以查看用户上次完成2FA身份验证的情况。如果超过30天,我会重新启用数据库中的2FA标志。然后,当执行密码登录时,我将按预期获得RequiresVerification,并且我可以继续其余的流程,因为任何标准的2FA验证都需要。