Microsoft Identity 2 SignInManager 从不 returns VerificationRequired
Microsoft Identity 2 SignInManager never returns VerificationRequired
我正在尝试使用电子邮件中发送的个人识别码添加双因素身份验证。用户仅在上次完成 2FA 步骤 30 天后才需要执行 2FA 步骤。
项目的技术是 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
我的问题
SignInManager 从不 returns 使用 PasswordSignIn 时需要验证
当 "TwoFactorEnabled" 标志在每个用户的数据库中设置为 true 时,我假设我应该期待这个登录状态。我不确定是否应该使用它,如果我只希望用户每 2 周进行一次 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。
如果用户已经 "successfully logged in with username and password",我如何防止他们简单地从验证屏幕跳到其他页面
此时他们不能绕过授权属性吗?
已经有效的方法
我可以让 UserManager 发送一封带有令牌(密码)的电子邮件,如果我输入正确的用户 ID,它将成功验证
我做了什么
我有 standard/default Identity 设置,所以我们几乎使用新 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 验证都需要。
我正在尝试使用电子邮件中发送的个人识别码添加双因素身份验证。用户仅在上次完成 2FA 步骤 30 天后才需要执行 2FA 步骤。
项目的技术是 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
我的问题
SignInManager 从不 returns 使用 PasswordSignIn 时需要验证 当 "TwoFactorEnabled" 标志在每个用户的数据库中设置为 true 时,我假设我应该期待这个登录状态。我不确定是否应该使用它,如果我只希望用户每 2 周进行一次 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。
如果用户已经 "successfully logged in with username and password",我如何防止他们简单地从验证屏幕跳到其他页面 此时他们不能绕过授权属性吗?
已经有效的方法 我可以让 UserManager 发送一封带有令牌(密码)的电子邮件,如果我输入正确的用户 ID,它将成功验证
我做了什么 我有 standard/default Identity 设置,所以我们几乎使用新 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 验证都需要。