我正在考虑在MVC中实现双因素身份验证,类似于Googles身份验证器。
由于某些用户不会设置两个因素身份验证,我们希望使用两个步骤 - 一个屏幕输入用户名和密码,另一个屏幕输入一次性密码。
我的难点是如何在用户输入一次性密码时安全存储用户的用户名和密码?目前我们收到密码并立即拒绝或发出cookie,因此我们不会将密码存储在任何地方。但是,通过两步,我们无法立即发出cookie,因为用户可以直接导航到另一个操作。同样,我不想将密码作为表单中的隐藏元素发回给用户。
这种情况的标准做法是什么?
我能想到的最好的方法是在会话中存储用户名和密码,但我不确定它有多安全。
答案 0 :(得分:7)
虽然答案已被接受,但我想我会添加一种不同的方式。 当您验证用户名和密码组合时,您无需记录用户,如果他们提供了正确的详细信息,那么您需要存储在临时数据中的是用户名或他们的个人资料(如果需要),然后将其重定向到第二个因子页面,只有一旦他们提供了正确的一次性密码,你才真正登录用户。
此方法避免了使用其他属性的需要,这可能会导致一致性。
这是关于如何实现它的相关摘要
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
var profile = MvcTFAProfile.GetProfile(model.UserName);
if (profile.UsesTwoFactorAuthentication)
{
TempData[CurrentUserTempDataKey] = profile;
TempData[RememberMeTempDataKey] = model.RememberMe;
return RedirectToAction("SecondFactor", new {returnUrl = returnUrl});
}
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
return RedirectToLocal(returnUrl);
}
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
以下链接包含有关如何在ASP.NET MVC中实现此功能的所有详细信息,文章以Google身份验证器为目标,这可能不是您正在使用的内容,但是如何将用户登录等原则是相同; https://samjenkins.com/mvc-two-factor-authentication/
答案 1 :(得分:4)
实际上,您不需要存储密码并等待身份验证,直到第二步通过。您可以单独执行两个身份验证步骤(每个步骤都是通常的身份验证:您可以立即进行身份验证或拒绝),并将相应的权限授予通过第一步和第二步的用户。
具体来说,您可以创建自己的AuthorizeConfirmedAttribute
派生的授权属性AuthorizeAttribute
,并将其用于第二步身份验证。因此,在您生成屏幕以输入一次性密码的控制器中,您使用通常的[Authorize]
属性,确保用户通过了第一步验证。在所有其他操作中,您使用[AuthorizeConfirmed]
属性来确保用户通过了身份验证的两个步骤。
答案 2 :(得分:2)
您应该查看ASP.NET Identity以获取双因素身份验证的示例流程。以下帖子有更多信息和指向示例http://blogs.msdn.com/b/webdev/archive/2014/02/11/announcing-preview-of-microsoft-aspnet-identity-2-0-0-beta1.aspx
的链接