安全地实施双因素身份验证

ber*_*oss 8 c# asp.net authentication asp.net-mvc-4

我正在考虑在MVC中实现双因素身份验证,类似于Googles身份验证器.

由于一些用户不会有两个因素身份验证设置,我们要使用两个步骤 - 一个屏幕输入用户名和密码,另一个屏幕输入一次性密码.

我的难点是如何在输入一次性密码时安全地存储用户的用户名和密码?目前我们收到密码并立即拒绝或发出cookie,因此我们不会将密码存储在任何地方.但是,通过两步,我们无法立即发出cookie,因为用户可以直接导航到另一个操作.同样,我不想将密码作为表单中的隐藏元素发回给用户.

这种情况的标准做法是什么?

我能想到的最好的方法是在会话中存储用户名和密码,但我不确定它有多安全.

Sat*_*tal 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);
}
Run Code Online (Sandbox Code Playgroud)

以下链接包含有关如何在ASP.NET MVC中实现此功能的所有详细信息,该文章的目标是Google身份验证器,它可能不是您正在使用的内容,但是如何将用户登录等原则是相同的; https://samjenkins.com/mvc-two-factor-authentication/


Mik*_*rov 5

实际上,您不需要存储密码并等待您的身份验证,直到第二步通过。您可以分别执行两步身份验证(每一步都与通常的身份验证一样:您立即进行身份验证或拒绝),并相应地向通过第一步和第二步的用户授予适当的权限。

具体来说,您可以创建自己的 Authorize 属性AuthorizeConfirmedAttributeAuthorizeAttribute并将其用于身份验证的第二步。因此,在您生成屏幕以输入一次性密码的控制器中,您使用通常的[Authorize]属性,确保用户通过了身份验证的第一步。在所有其他操作中,您使用该[AuthorizeConfirmed]属性来确保用户通过了您的验证的两个步骤。