public ActionResult SignIn(SignInInput input, string returnUrl) { this.ViewData.Model = new SignInViewModel(input); if (!this.ModelState.IsValid) { return View().WithStatus(HttpStatusCode.BadRequest); } var result = this.auth.SignIn(input); if (result.IsError) { return View().WithErrors(result); } string location = GetValidReturnUrl(returnUrl); return Redirect(location); }
OperationResult SignInImpl(SignInInput input) { var result = ValidateUser(input); if (result.IsError) return result; this.formsAuthService.SetAuthCookie(result.ValueAsSuccess, input.RememberMe); return HttpStatusCode.OK; }
OperationResult<string> ValidateUser(SignInInput input) { if (input == null) throw new ArgumentNullException("input"); var errors = new ErrorBuilder(); if (errors.NotValid(input)) return errors; string userPassNotMatchMessage = AccountResources.Validation_UserPassNotMatch.FormatInvariant(AccountResources.Model_Username); UserWrapper user = this.repo.FindUserByName(input.Username); if (errors.Not(user != null, userPassNotMatchMessage)) return errors; DateTime now = this.Configuration.GetNow(); if (!user.Password.HasValue()) return new OperationResult<string>(HttpStatusCode.Forbidden, AccountResources.Validation_MissingPasswordCannotAuthenticate); int maxInvalidAttempts = this.Configuration.MaxInvalidSignInAttempts; bool passwordCorrect = this.passServ.PasswordEquals(input.Password, user.Password); int failedAttempts = user.FailedSignInAttempts; if (passwordCorrect) { if (user.Disabled) return new OperationResult<string>(HttpStatusCode.Forbidden, AccountResources.Validation_UserDisabled); } else { if (user.Disabled) return new OperationResult<string>(HttpStatusCode.BadRequest, userPassNotMatchMessage); if (failedAttempts <= maxInvalidAttempts) { failedAttempts++; user.FailedSignInAttempts = failedAttempts; user.FailedSignInAttemptWindowStart = now; if (failedAttempts > maxInvalidAttempts && this.Configuration.DisableOnMaxInvalidSignInAttempts && !user.Disabled) { user.Disabled = true; } this.repo.UpdateUser(user); if (failedAttempts <= maxInvalidAttempts || user.Disabled) { return new OperationResult<string>(HttpStatusCode.BadRequest, userPassNotMatchMessage); } } } if (failedAttempts > maxInvalidAttempts) { DateTime lockEnd = user.FailedSignInAttemptWindowStart.GetValueOrDefault().Add(this.Configuration.SignInAttemptWindow); TimeSpan timeLeft = (lockEnd > now) ? lockEnd.Subtract(now) : TimeSpan.MinValue; double totalMinutes = timeLeft.TotalMinutes; double minutes = Math.Ceiling(totalMinutes); if (minutes > 0) { return new OperationResult<string>( HttpStatusCode.Forbidden, AccountResources.Validation_MaxInvalidSignInAttempts.FormatInvariant(minutes) ); } } if (passwordCorrect) { user.FailedSignInAttempts = 0; user.FailedSignInAttemptWindowStart = null; user.LastSignIn = now; } else { // Window passed but password is incorrect, restart failed attempts count user.FailedSignInAttempts = 1; user.FailedSignInAttemptWindowStart = now; } this.repo.UpdateUser(user); if (!passwordCorrect) return new OperationResult<string>(HttpStatusCode.BadRequest, userPassNotMatchMessage); return user.Username; }
public ActionResult SignIn(SignInInput input, string returnUrl) { this.ViewData.Model = new SignInViewModel(input); if (!this.ModelState.IsValid) return View().WithStatus(HttpStatusCode.BadRequest); var result = SignInImpl(input); if (result.IsError) return View().WithErrors(result); string location = GetValidReturnUrl(returnUrl); return HttpSeeOther(location); }