Microsoft Identity 2 SignInManager 从不返回 VerificationRequired
Posted
技术标签:
【中文标题】Microsoft Identity 2 SignInManager 从不返回 VerificationRequired【英文标题】:Microsoft Identity 2 SignInManager never returns VerificationRequired 【发布时间】:2019-08-11 00:11:13 【问题描述】:我正在尝试使用电子邮件中发送的 PIN 码添加 2 因素身份验证。用户仅在上次完成 2FA 步骤 30 天后才需要执行 2FA 步骤。
项目的技术是使用 EntityFramework 6 的 ASP.NET MVC 5 和 Microsoft.AspNet.Identity 包(.Core、.EntityFramework、.Owin)的 NuGet 包版本 2.2.2。
我一直遵循本教程中的建议,但将其集成到我公司现有的解决方案中:https://docs.microsoft.com/en-us/aspnet/identity/overview/features-api/two-factor-authentication-using-sms-and-email-with-aspnet-identity
我的问题
SignInManager 在使用 PasswordSignIn 时从不返回 RequiresVerification 我假设当每个用户在数据库中将“TwoFactorEnabled”标志设置为 true 时,我应该期待这种登录状态。我不确定我是否应该使用它,如果我只希望用户每两周通过一次 2FA 验证,因为我的印象是它需要用户每次都通过这个。要么这样,要么我应该使用在用户上设置的时间戳来确定是否该重新启用“TwoFactorEnabled”标志?
验证代码时,我无法检索已验证用户的 ID 我认为在执行正常的 PasswordSignIn 之后,服务器将能够检索用户的 ID,例如在验证输入的 pin 码是否正确时:
[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。
如果用户已经“使用用户名和密码成功登录”,我如何防止用户直接从验证屏幕跳到其他页面 他们现在不能绕过 Authorization 属性吗?
已经有效的方法 我可以让 UserManager 发送带有令牌(pin 码)的电子邮件,如果我输入正确的用户 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;
非常感谢您的任何帮助。
【问题讨论】:
只是为了确认:在您的浏览器中设置了第一级身份验证后的cookies吗?如果应用程序使用 google chrome 在开发模式下运行,您将无法为 localhost 域设置 cookie。你需要有一个注册表控制的域。这是 chrome 中的一个已知安全问题。尝试在其他浏览器上运行。参考问题:bugs.chromium.org/p/chromium/issues/detail?id=56211 另一方面,您可以在 proect 属性中将应用程序的 SSL 设置为 true,并将 https 链接复制到您的 Web 属性以规避问题,以便能够在 chrome 中工作 @bhanu.cs 我现在要做的是: 1. 用户在 AJAX 请求中将用户名和密码发送到名为 login 的 JsonResult 方法。 2. 在此方法中,我使用 SignInManager 执行登录。我将 SignInStatus 和 ApplicationUser 传递给打开 SignInStatus 的方法。 3.如果 SignInStatus 为 Success,我现在只需检查用户的声明值,其中包含日期。如果日期超过 30 天,我会向他们发送一个密码并重定向到验证代码页面,他们必须在其中输入密码。此外,如果是这种情况,我没有为用户设置任何会话变量,但我已经执行了 PasswordSignIn,这可能有问题?当他们提交他们的 pin 码时,我只设置了一个包含他们的 UserId 的 Session 变量。 哦,我明白了,这是您想到的一个聪明的解决方法。但是在第 3 步中,由于 2FA 已启用,SignInManager 返回 RequireVerification 状态,并且在 2FA 完成之前不会生成 auth cookie(尽管生成了其他中间 cookie,但我不确定这一点),这将使您无法通过身份验证。您是否考虑过这个案例?简而言之,如果在提供电话代码或电子邮件代码之前启用 2FA,您可能无法通过身份验证。 【参考方案1】:我想我可能已经弄清楚问题所在了。 UserManager 为 GetValidTwoFactorProvidersAsync 返回 0。当没有为用户确认电子邮件时,似乎会发生这种情况。我尝试为用户确认设置电子邮件,现在返回 RequiresVerification。
返回 RequiresVerification 时,用户似乎没有完全登录,但我仍然能够使用 SignInManager 的 GetVerifiedUserId 方法在后续代码验证调用中获取用户 ID。
所以现在,当用户登录时,在执行密码登录之前,我只需执行检查以查看用户上次完成 2FA 身份验证的时间。如果超过 30 天,我会重新启用数据库中的 2FA 标志。然后,当执行密码登录时,我将按预期获得 RequiresVerification,然后我可以继续其余流程,因为任何标准 2FA 验证都需要其他方式。
【讨论】:
以上是关于Microsoft Identity 2 SignInManager 从不返回 VerificationRequired的主要内容,如果未能解决你的问题,请参考以下文章
The identity used to sign the executable is no longer valid.
Xcode真机调试失败:The identity used to sign the executable is no longer valid
更新 Microsoft.AspNet.Identity.Owin 2.2.0 后启动时处理 Ninject 内核
the identity used to sign the executable is no longer valid.解决方法