Reliable implementation of two-factor authentication

I am learning implementation of two-factor authentication in MVC, similar to Google authenticator.

Since some users will not have two fax authentication settings, we want to use a two-step process — one screen to enter a username and password, and the other screen a one-time password.

My difficulty is how do you safely save users username and password while they enter their one-time password? We are currently receiving a password and immediately rejecting or issuing a cookie, so we do not store the password anywhere. However, with two steps, we cannot immediately release the cookie, because the user can simply move on to another action. Equally, I do not want to send the password back to the user as a hidden element in the form.

What is the standard practice for this situation?

The best I can think of is to keep the username and password in the session, but I'm not sure how secure it is.

+4
source share
3 answers

In fact, you do not need to store a password and wait with your authentication until the second step is taken. You can simply implement the two steps of your authentication separately (each step is basic authentication: you immediately authenticate or reject) and grant the appropriate privileges to users who have passed the first step and second step, respectively.

In particular, you can create your own Authorize AuthorizeConfirmedAttribute attribute, obtained from AuthorizeAttribute , and use it for your second authentication step. So, in the controller, where you create the screen for entering the password, you use the usual [Authorize] attribute, which ensures that the user has passed the first authentication step. In all other actions, you use the [AuthorizeConfirmed] attribute to ensure that the user passes both authentication steps.

+4
source

Although the answer has already been accepted, I thought I would add another way. You do not need to register a user when you check their username and password combination, if they provided the correct data, all you need to store in temporary data is their username or their profile if you want, and then redirect them to the second page of the factor, which only after they provided the correct one-time password do you actually register the user.

This method avoids the need for additional attributes, which can be a pain for consistency.

This is an appropriate fragment on how to achieve it.

 [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); } 

The following link contains all the information on how to implement this in ASP.NET MVC, the article is aimed at Google Authenticator, maybe this is not what you are working with, but the principle of user registration in etc. same; https://samjenkins.com/mvc-two-factor-authentication/

+5
source

You should look at the ASP.NET identifier for the fetch stream for two-factor authentication. The following post contains additional information and links to a sample http://blogs.msdn.com/b/webdev/archive/2014/02/11/announcing-preview-of-microsoft-aspnet-identity-2-0-0-beta1 .aspx

+2
source

Source: https://habr.com/ru/post/1494426/


All Articles