public void LogOnAsync(LogOnModel model, string returnUrl)
 {
     AsyncManager.OutstandingOperations.Increment();
     AsyncManager.Parameters["task"] = Task.Factory.StartNew(() => { DoLogOn(model, returnUrl); });
 }
        public ActionResult LogOnCompleted(Task task, string returnUrl, string action, string controller, LogOnModel model)
        {
            try
            {
                task.Wait();
            }
            catch (AggregateException ex)
            {
                Exception baseException = ex.GetBaseException();

                if (baseException is OneTimePasswordException)
                {
                    model = new LogOnModel();
                    ModelState.AddModelError("", "This two factor code has already been used. Please wait for the next code to be generated and try again.");
                }
                else
                {
                    throw;
                }
            }

            if (returnUrl != null)
            {
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                return Redirect(returnUrl);
            }
            else if (action != null && controller != null)
            {
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                return RedirectToAction(action, controller);
            }
            else
            {
                return View(model);
            }
        }
        //
        // POST: /Account/LogOn
        private void DoLogOn(LogOnModel model, string returnUrl)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    if (Membership.ValidateUser(model.UserName, model.Password))
                    {
                        var profile = TwoFactorProfile.GetByUserName(model.UserName);

                        if (profile != null && !string.IsNullOrEmpty(profile.TwoFactorSecret))
                        {
                            // Prevent the user from attempting to brute force the two factor secret.
                            // Without this, an attacker, if they know your password already, could try to brute
                            // force the two factor code. They only need to try 1,000,000 distinct codes in 3 minutes.
                            // This throttles them down to a managable level.
                            if (profile.LastLoginAttemptUtc.HasValue && profile.LastLoginAttemptUtc > DateTime.UtcNow - TimeSpan.FromSeconds(1))
                            {
                                System.Threading.Thread.Sleep(5000);
                            }

                            profile.LastLoginAttemptUtc = DateTime.UtcNow;

                            if (TimeBasedOneTimePassword.IsValid(profile.TwoFactorSecret, model.TwoFactorCode))
                            {
                                if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                                    && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                                {
                                    AsyncManager.Parameters["returnUrl"] = returnUrl;
                                }
                                else
                                {
                                    AsyncManager.Parameters["action"] = "Index";
                                    AsyncManager.Parameters["controller"] = "Home";
                                }
                            }
                            else
                            {
                                ModelState.AddModelError("", "The two factor code is incorrect.");
                            }
                        }
                        else
                        {
                            ModelState.AddModelError("", "The two factor code is incorrect.");
                        }
                    }
                    else
                    {
                        ModelState.AddModelError("", "The user name or password provided is incorrect.");
                    }
                }

                AsyncManager.Parameters["model"] = model;
            }
            finally
            {
                AsyncManager.OutstandingOperations.Decrement();
            }
        }