4

On my login page I want to implement a system, whereby if the user exists but doesn't have a confirmed email (IsEmailConfirmed), the user needs to verify/confirm the email.

I don't have any problem re-sending the confirmation code, my issue is where to put the statement and how make sure the users enter the correct username and password (Users should be valid).

Login (Code Behind)

protected void LogIn(object sender, EventArgs e)
{
  // Validate the user password
  var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
  var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();

  // Require the user to have a confirmed email before they can log on.
  var user = manager.FindByName(username.Text);

  if (IsValid)
   {
    if (user != null)
     {
      // This doen't count login failures towards account lockout
      // To enable password failures to trigger lockout, change to shouldLockout: true
      var result = signinManager.PasswordSignIn(username.Text, Password.Text, RememberMe.Checked, shouldLockout: true);

      switch (result)
       {
        case SignInStatus.Success:
        IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], 
                                                           Response);
        break;

        case SignInStatus.LockedOut:
         //Response.Redirect("/Account/Lockout");    
         FailureText.Text = "This account has been locked out, please try again later.";
         ErrorMessage.Visible = true;
         return;

        case SignInStatus.RequiresVerification:
          Response.Redirect(String.Format("/Account/TwoFactorAuthenticationSignIn?ReturnUrl={0}&RememberMe={1}",
          Request.QueryString["ReturnUrl"],
          RememberMe.Checked),
          true);
          break;

         case SignInStatus.Failure:
         default:
          FailureText.Text = "Invalid login attempt";
          ErrorMessage.Visible = true;
          break;    
          }   
        }
      }    
  else
  {
     FailureText.Text = "Account not found.";
     ErrorMessage.Visible = true;
  }

  //else if (IsValid & !manager.IsEmailConfirmed(user.Id))
  //{
     //    ScriptManager.RegisterStartupScript(this, this.GetType(), "LaunchServerSide", "$(function() { OpenLoginModal(); });", true);
        //    LoginModalTitle.Text = "Account Verification".ToUpper();
        //    LoginModalDetails.Text = "You must have a confirmed email account.";
        //    //ErrorMessage.Visible = true;
        //    //ResendConfirm.Visible = true;
        //}
 }

I appreciate your efforts in reaching a solution for my problem

Sakthivel
  • 1,890
  • 2
  • 21
  • 47
Kevin Maxwell
  • 907
  • 2
  • 19
  • 38
  • if it is inside an `if-else` statement it doesn't matter where you put it as long as it has the requirements specified. And for the user to have the correct `username` and `password` this is the basics of the login. You need to verify it if it exists any users with those credentials. P.s. skipped a bit of your question there that's why i deleted my comment. – xhulio Aug 06 '15 at 12:14
  • You're right. I've already tried that but when the user enters an invalid password instead of showing "Invalid login attempt" it actually runs my email verification statement. – Kevin Maxwell Aug 06 '15 at 12:18
  • that's becuase you check only if the user exists and not if the credentials are the correct ones – xhulio Aug 06 '15 at 12:19

3 Answers3

3

If I understand correct: You want to make sure that both username and password is correct before we check if account is active?

protected void LogIn(object sender, EventArgs e)
{
    var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
    var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();
    var user = manager.FindByName(username.Text);

    if (IsValid)
    {
        if (user != null)
        {
            var result = signinManager.PasswordSignIn(username.Text, Password.Text, RememberMe.Checked, shouldLockout: true);

            // If username and password is correct check if account is activated.
            if(!user.EmailConfirmed && result == SignInStatus.Success)
            {
                FailureText.Text = "Invalid login attempt. You must have a confirmed email account.";
                ErrorMessage.Visible = true;
                return;
            }        

            switch (result)
            {
                case SignInStatus.Success:
                    IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], 
                                                           Response);
                    break;
                case SignInStatus.LockedOut:
                    //Response.Redirect("/Account/Lockout");    
                    FailureText.Text = "This account has been locked out, please try again later.";
                    ErrorMessage.Visible = true;
                    return;

                case SignInStatus.RequiresVerification:
                    Response.Redirect(String.Format("/Account/TwoFactorAuthenticationSignIn?ReturnUrl={0}&RememberMe={1}",
                                                    Request.QueryString["ReturnUrl"],
                                                    RememberMe.Checked),
                                                    true);
                    break;
                case SignInStatus.Failure:
                default:
                    FailureText.Text = "Invalid login attempt";
                    ErrorMessage.Visible = true;
                    break;    
            }                
        }    
        else
        {
            FailureText.Text = "Account not found.";
            ErrorMessage.Visible = true;
        }
    }
}
Joachim
  • 360
  • 2
  • 12
2

A slight modification is needed to check if the user is confirmed. You need to check the IsEmailConfirmed property to see if the user has confirmed the account or not.

This article explains the flow and how to perform these actions pretty nicely. Snippet below is snatched from that article.

    var user = manager.FindByName(Email.Text);
    if (user != null)
    {
        if (!user.EmailConfirmed)
        {
            FailureText.Text = "Invalid login attempt. You must have a confirmed email address. Enter your email and password, then press 'Resend Confirmation'.";
            ErrorMessage.Visible = true;
            ResendConfirm.Visible = true;
        }
        else
        {
             // your other logic goes here if the user is confirmed.
             ....
        }
    }
    else 
    {
        // user does not exist.
    }
scheien
  • 2,457
  • 1
  • 19
  • 22
0

in .NET 7 Login.cshtml.cs

                if (result.IsLockedOut)
            {
                _logger.LogWarning("User account locked out.");
                return RedirectToPage("./Lockout");
            }
            if (result.IsNotAllowed)
            {
                var user = _signInManager.UserManager.FindByEmailAsync(Input.Email);
                if (user != null)
                {
                    if (!user.Result.EmailConfirmed)
                    {
                        ModelState.AddModelError(string.Empty, "Account isn't active, Get Your Email & click on Active link, ");
                    }
                }
                else
                {
                    ModelState.AddModelError(string.Empty, "incorrect username or password");//Email not found
                }
            }
            else
            {
                ModelState.AddModelError(string.Empty, "incorrect username or password");
                return Page();
            }
مهدی
  • 333
  • 3
  • 6
  • When the user is not confirmed it will get an error but is logged in. Also call await _signInManager.SignOutAsync(); to signe the user out again. – Dragon Ace Jul 16 '23 at 12:16