安全地实现双因素身份验证
本文关键字:身份验证 实现 安全 | 更新日期: 2023-09-27 18:25:47
我正在研究在MVC中实现双因素身份验证,类似于Google验证器。
由于有些用户没有双因素身份验证设置,我们希望使用两步流程——一个屏幕输入用户名和密码,另一个屏幕则输入一次性密码。
我的困难在于,当用户输入一次性密码时,如何安全地存储用户名和密码?目前,我们收到密码后会立即拒绝或发布cookie,因此我们不会将密码存储在任何地方。然而,通过两步操作,我们不能立即发布cookie,因为用户可以简单地导航到另一个操作。同样,我不想将密码作为表单中的隐藏元素发送回用户
这种情况的标准做法是什么?
我能想到的最好的办法是将用户名和密码存储在会话中,但我不确定这有多安全。
虽然已经接受了答案,但我想添加一种不同的方式。当你验证用户的用户名和密码组合时,你不需要让用户登录,如果他们提供了正确的详细信息,你只需要在临时数据中存储他们的用户名或个人资料(如果你愿意的话),然后将他们重定向到第二因素页面,只有当他们提供正确的一次性密码后,你才能真正让用户登录。
这种方法避免了具有额外属性的需要,这可能会给一致性带来麻烦。
这是关于如何实现的相关片段
[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 Authenticator,这可能不是你正在使用的,但如何登录用户等的原理是相同的;https://samjenkins.com/mvc-two-factor-authentication/
实际上,您不需要存储密码并等待身份验证,直到第二步通过。您只需分别实现身份验证的两个步骤(每个步骤都是常规身份验证:您立即进行身份验证或拒绝),并相应地向通过第一步和第二步的用户授予适当的权限。
具体来说,您可以从AuthorizeAttribute
派生出自己的Authorize属性AuthorizeConfirmedAttribute
,并将其用于第二步身份验证。因此,在生成屏幕以输入一次性密码的控制器中,使用通常的[Authorize]
属性,确保用户通过了第一步身份验证。在所有其他操作中,您使用[AuthorizeConfirmed]
属性来确保用户通过了身份验证的两个步骤。
您应该查看ASP.NET Identity以获得双因素身份验证的示例流。下面的帖子有更多的信息和链接到样本http://blogs.msdn.com/b/webdev/archive/2014/02/11/announcing-preview-of-microsoft-aspnet-identity-2-0-0-beta1.aspx