0

Ive got a problem: my websecurity always throws false on confirmation. What am I doing wrong? Here is my Validate Action(Ive debugged it, the id received is the right confirmation token:

    public ActionResult Validate(String Id)
    {
        if (String.IsNullOrEmpty(Id))
        {
            return View();
        }
        bool b = WebSecurity.ConfirmAccount(Id);
        if (b)
        {
            return View("ConfirmationSuccess");
        }
        return View("ConfirmationFailure");
    }

And here is my registration action:

 public ActionResult Register(RegisterModel model, string ReturnUrl)
    {
        if (ModelState.IsValid)
        {
            // Попытка зарегистрировать пользователя
            try
            {
                string confirmationToken = WebSecurity.CreateUserAndAccount(model.rEmail.ToLower(), model.rPassword, null, true);
                dynamic email = new Email("~/Views/Emails/RegisterConfirmation.cshtml");
                email.To = model.rEmail;
                email.ConfirmationToken = confirmationToken;
                email.Send();
                return RedirectToAction("EmailValidation", new { Email = model.rEmail.ToLower() });
            }
            catch (MembershipCreateUserException e)
            {
                string field = string.Empty;
                switch (e.StatusCode)
                {
                    case MembershipCreateStatus.DuplicateUserName:
                        field = "rEmail";
                        break;
                    case MembershipCreateStatus.InvalidPassword:
                        field = "rPassword";
                        break;
                    default:
                        field = "RegisterForm";
                        break;
                }
                ModelState.AddModelError(field, ErrorCodeToString(e.StatusCode));
            }
        }
        ViewBag.RegisterModel = model;
        ViewBag.ReturnUrl = ReturnUrl;
        ViewBag.LoginModel = new LoginModel();
        //ModelState.AddModelError("rEmail", "Пользователь с таким e-mail уже зарегистрирован");
        // Появление этого сообщения означает наличие ошибки; повторное отображение формы
        return View("Login");
    }

after registration the email is sent, the link is the right link, but when It goes to WebSecurity.ConfirmAccount(Id), it always throws false....

Thank you for your time and sorry for my bad English.

UPD: There is a converter for all urls to lower on my IIS server. Could it be the case, that it compares keys case-sensitive? And how can I fix this?

UPD: Ok, the problem is really in lowercase url. WebSecurity.ConfirmAccount is case-sensitive... Ive made a little workaround in my action so that I could get the right ConfitmtionToken, but this is not fully right way, while there could be two identical ConfirmationToken.ToLower() as I think, So, please, somebody, point me the right way to do it. And here is my workaround:

public ActionResult Validate(String Id)
    {
        if (String.IsNullOrEmpty(Id))
        {
            return View();
        }
        //bool b = WebSecurity.ConfirmAccount(Id);
        using (var ctx = new DBContext())
        {
            Id = ctx.wpMembership.Where(s => s.ConfirmationToken.Equals(Id, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault().ConfirmationToken;
        }

        if (WebSecurity.ConfirmAccount(Id))
        {
            return View("ConfirmationSuccess");
        }
        return View("ConfirmationFailure");
    }
CodeDemen
  • 1,841
  • 3
  • 17
  • 30
  • English is not that bad actually :) – Patrick Magee Mar 16 '13 at 17:04
  • What happens if you try replacing your create user with this: WebSecurity.CreateUserAndAccount("username", "password", requireConfirmationToken: true); – Patrick Magee Mar 16 '13 at 17:11
  • thank you! But the same thing... I've updated my post with some more info – CodeDemen Mar 16 '13 at 17:24
  • Are you sure you are declaring the correct tables aswell? if (!WebSecurity.Initialized) { WebSecurity.InitializeDatabaseConnection( connectionStringName: "DefaultConnection", userTableName: "User", userIdColumn: "Id", userNameColumn: "Email", autoCreateTables: false); } – Patrick Magee Mar 16 '13 at 17:27
  • Why do you have a converter which does this? If you want lower case MVC controller actions you can always do routes.LowercaseUrls = true; in your RouteConfig – Patrick Magee Mar 16 '13 at 17:30
  • Yes, the init of websecurity is 100% correct. And it works fine everywhere except WebSecurity.ConfirmAccount. – CodeDemen Mar 16 '13 at 17:33
  • The converter is IIS UrlRewrite with rule for seo purposes. – CodeDemen Mar 16 '13 at 17:34

1 Answers1

1

This is because you are passing the account Id not the confirmation token. You need to pass the confirmation token.

The confirmation token is generated by the CreateAccount(String, String, Boolean), CreateUserAndAccount(String, String, Object, Boolean), and GeneratePasswordResetToken(String, Int32) methods. The token is ordinarily sent to the user as a link in an email message, and the user clicks the link in order to verify his or her identity.

Sajid Ali
  • 719
  • 2
  • 7
  • 21