Search code examples
asp.net-membershipsimplemembership

Best way to distinguish between invalid password and unconfirmed account.


What is the best way to figure out an account wasn't confirmed versus an invalid password.

Here is the scenario that I have:

  1. User Registers
  2. Confirmation token is created and an email was sent.
  3. User tries to login.

At this point, we don't know if the use is typing an invalid password && hasn't confirmed yet.

I have this block of code but It seems not right to me.

  {
      if (ModelState.IsValid)
      {
        if (WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
        {
          return RedirectToLocal(returnUrl);
        }
        else if (WebSecurity.IsConfirmed(model.UserName) == false)
        {
          ModelState.AddModelError("", "The user account was not confirmed. Please check your email and try again");
          return View(model);
        }
      }

There has to be a way that it can be done cleaner. Any ideas?

Thanks,


Solution

  • Your method for checking is pretty close. I have used the following code for log in that checks the confirmation.

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Login(LoginModel model, string returnUrl)
        {
            string errorMsg = "The user name or password provided is incorrect.";
    
            if (model.IsConfirmed)
            {
                if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
                {
                    return RedirectToLocal(returnUrl);
                }
                else if (WebSecurity.FoundUser(model.UserName) && !WebSecurity.IsConfirmed(model.UserName))
                {
                    model.IsConfirmed = false;
                    errorMsg = "You have not completed the registration process. To complete this process look for the email that provides instructions or press the button to resend the email.";
                }
    
            }
            else //Need to resend confirmation email
            {
                ResendConfirmationEmail(model.UserName);
                errorMsg = "The registration email has been resent. Find the email and follow the instructions to complete the registration process.";
                model.IsConfirmed = true;
            }
    
            // If we got this far, something failed, redisplay form
            ModelState.AddModelError("", errorMsg );
            return View(model);
        }
    

    You will notice that the main difference is that you need to also check that the user is in the system with the method FoundUser, otherwise IsConfirmed will return false if a bad user name is passed in. In this scenario I added an IsConfirmed property to the View Model. This is used in the View to determine if a button is displayed that allows the user to have the confirmation email resent to them in case they lost it. You can read more details about this approach in this article.