public async Task <IActionResult> LoginWith2fa(LoginWith2faViewModel model, bool rememberMe, string returnUrl = "/") { returnUrl = "/"; if (!ModelState.IsValid) { return(View(model)); } var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); if (user == null) { throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); } var authenticatorCode = model.TwoFactorCode.Replace(" ", string.Empty).Replace("-", string.Empty); var result = await _signInManager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, rememberMe, model.RememberMachine); if (result.Succeeded) { _logger.LogInformation("User with ID {UserId} logged in with 2fa.", user.Id); return(RedirectToLocal(returnUrl)); } else if (result.IsLockedOut) { _logger.LogWarning("User with ID {UserId} account locked out.", user.Id); return(RedirectToAction(nameof(Lockout))); } else { _logger.LogWarning("Invalid authenticator code entered for user with ID {UserId}.", user.Id); ModelState.AddModelError(string.Empty, "Invalid authenticator code."); return(View()); } }
public async Task <IActionResult> Login(LoginViewModel model, string returnUrl = null) { if (!CanLoginOrRegister()) { return(RedirectToAction("Login")); } ViewData["ReturnUrl"] = returnUrl; if (ModelState.IsValid) { // Require the user to have a confirmed email before they can log on. var user = await _userManager.FindByEmailAsync(model.Email); if (user != null) { if (user.RequiresEmailConfirmation && !await _userManager.IsEmailConfirmedAsync(user)) { ModelState.AddModelError(string.Empty, "You must have a confirmed email to log in."); return(View(model)); } } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return(View(model)); } var u2fDevices = await _u2FService.HasDevices(user.Id); var fido2Devices = await _fido2Service.HasCredentials(user.Id); if (!await _userManager.IsLockedOutAsync(user) && u2fDevices || fido2Devices) { if (await _userManager.CheckPasswordAsync(user, model.Password)) { LoginWith2faViewModel twoFModel = null; if (user.TwoFactorEnabled) { // we need to do an actual sign in attempt so that 2fa can function in next step await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure : true); twoFModel = new LoginWith2faViewModel { RememberMe = model.RememberMe }; } return(View("SecondaryLogin", new SecondaryLoginViewModel() { LoginWith2FaViewModel = twoFModel, LoginWithU2FViewModel = u2fDevices? await BuildU2FViewModel(model.RememberMe, user) : null, LoginWithFido2ViewModel = fido2Devices? await BuildFido2ViewModel(model.RememberMe, user): null, })); } else { var incrementAccessFailedResult = await _userManager.AccessFailedAsync(user); ModelState.AddModelError(string.Empty, "Invalid login attempt."); return(View(model)); } } var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure : true); if (result.Succeeded) { _logger.LogInformation($"User '{user.Id}' logged in."); return(RedirectToLocal(returnUrl)); } if (result.RequiresTwoFactor) { return(View("SecondaryLogin", new SecondaryLoginViewModel() { LoginWith2FaViewModel = new LoginWith2faViewModel() { RememberMe = model.RememberMe } })); } if (result.IsLockedOut) { _logger.LogWarning($"User '{user.Id}' account locked out."); return(RedirectToAction(nameof(Lockout))); } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return(View(model)); } } // If we got this far, something failed, redisplay form return(View(model)); }
public async Task <IActionResult> LoginWith2fa(LoginWith2faViewModel model, bool rememberMe, string returnUrl = null) { ViewData["Title"] = sr["Two-factor authentication"]; if (!ModelState.IsValid) { return(View(model)); } //var user = await accountService.GetTwoFactorAuthenticationUserAsync(); //if (user == null) //{ // throw new ApplicationException($"Unable to load user with ID '{User.GetUserId()}'."); //} //var authenticatorCode = model.TwoFactorCode.Replace(" ", string.Empty).Replace("-", string.Empty); //var result = await accountService.TwoFactorAuthenticatorSignInAsync(authenticatorCode, rememberMe, model.RememberMachine); //if (result.Succeeded) //{ // if (!string.IsNullOrEmpty(returnUrl)) // { // return LocalRedirect(returnUrl); // } // return this.RedirectToSiteRoot(Site); //} //if (result.IsLockedOut) //{ // return HandleLockout(); //} //else //{ // ModelState.AddModelError(string.Empty, "Invalid authenticator code."); // return View(model); //} var result = await accountService.Try2FaLogin(model, rememberMe); if (result.SignInResult.Succeeded) { return(await HandleLoginSuccess(result, returnUrl)); } foreach (var reason in result.RejectReasons) { //these reasons are not meant to be shown in the ui // but we can log them so admin will see failed attempts in the log along with reasons log.LogWarning(reason); } if (result.SignInResult.IsNotAllowed) { return(HandleLoginNotAllowed(result)); } if (result.SignInResult.IsLockedOut) { return(HandleLockout(result)); } else { analytics.HandleLoginFail("Onsite", sr["Invalid authenticator code."]).Forget(); ModelState.AddModelError(string.Empty, sr["Invalid authenticator code."]); return(View(model)); } }
public async Task <IActionResult> Login(LoginViewModel model, string returnUrl = null) { ViewData["ReturnUrl"] = returnUrl; if (ModelState.IsValid) { // Require the user to have a confirmed email before they can log on. var user = await _userManager.FindByEmailAsync(model.Email); if (user != null) { if (user.RequiresEmailConfirmation && !await _userManager.IsEmailConfirmedAsync(user)) { ModelState.AddModelError(string.Empty, "Debe tener un correo electrónico confirmado para iniciar sesión."); return(View(model)); } } else { ModelState.AddModelError(string.Empty, "Intento de inicio de sesión no válido."); return(View(model)); } if (!await _userManager.IsLockedOutAsync(user) && await _u2FService.HasDevices(user.Id)) { if (await _userManager.CheckPasswordAsync(user, model.Password)) { LoginWith2faViewModel twoFModel = null; if (user.TwoFactorEnabled) { // we need to do an actual sign in attempt so that 2fa can function in next step await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure : true); twoFModel = new LoginWith2faViewModel { RememberMe = model.RememberMe }; } return(View("SecondaryLogin", new SecondaryLoginViewModel() { LoginWith2FaViewModel = twoFModel, LoginWithU2FViewModel = await BuildU2FViewModel(model.RememberMe, user) })); } else { var incrementAccessFailedResult = await _userManager.AccessFailedAsync(user); ModelState.AddModelError(string.Empty, "Intento de inicio de sesión no válido."); return(View(model)); } } var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure : true); if (result.Succeeded) { _logger.LogInformation("Usuario conectado."); return(RedirectToLocal(returnUrl)); } if (result.RequiresTwoFactor) { return(View("SecondaryLogin", new SecondaryLoginViewModel() { LoginWith2FaViewModel = new LoginWith2faViewModel() { RememberMe = model.RememberMe } })); } if (result.IsLockedOut) { _logger.LogWarning("Cuenta de usuario bloqueada."); return(RedirectToAction(nameof(Lockout))); } else { ModelState.AddModelError(string.Empty, "Intento de inicio de sesión no válido."); return(View(model)); } } // If we got this far, something failed, redisplay form return(View(model)); }
public async Task <IActionResult> Post([FromBody] LoginWith2faViewModel model) { var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); if (user == null) { return(BadRequest(Errors.AddErrorToModelState("user loading failure", "Unable to load user", ModelState))); } var authenticatorCode = model.TwoFactorCode.Replace(" ", string.Empty).Replace("-", string.Empty); var result = await _signInManager.TwoFactorSignInAsync("Phone", authenticatorCode, false, false); if (result.Succeeded) { var identity = await GetClaimsIdentity(user.UserName); var profile = _ctx.UserProfiles.FirstOrDefault(t => t.UserId == user.Id); //check if user has refresh token var validRefreshToken = _ctx.RefreshTokens.FirstOrDefault(r => r.UserId == user.Id.ToString() && r.IsEnabled); if (validRefreshToken != null) { if (validRefreshToken.EndDate.AddMinutes(-30) < DateTime.UtcNow) { //create new refresh token RefreshToken rt = new RefreshToken(); rt.StartDate = DateTime.UtcNow; DateTime dtmRefreshTokenEndDate = DateTime.UtcNow; dtmRefreshTokenEndDate = dtmRefreshTokenEndDate.AddMonths(6); rt.EndDate = dtmRefreshTokenEndDate; rt.IsEnabled = true; rt.UserId = user.Id; bool refreshTokenAdded = false; refreshTokenAdded = await _sqlServerUow.RefreshTokens.AddAsync(rt); // Serialize and return the response var response = new { id = user.Id, auth_token = await _jwtFactory.GenerateEncodedToken(user.UserName, identity), auth_token_valid = (int)_jwtOptions.ValidFor.TotalSeconds, auth_token_created = _jwtOptions.IssuedAt, auth_token_expires = _jwtOptions.Expiration, refresh_token = rt.RefreshTokenId, two_factor_auth_enabled = true, phone_number = user.PhoneNumber, email = user.Email, first_name = profile.FirstName, surname = profile.Surname }; var json = JsonConvert.SerializeObject(response, _serializerSettings); return(new OkObjectResult(json)); } else { // Serialize and return the response var response = new { id = user.Id, auth_token = await _jwtFactory.GenerateEncodedToken(user.UserName, identity), auth_token_valid = (int)_jwtOptions.ValidFor.TotalSeconds, auth_token_created = _jwtOptions.IssuedAt, auth_token_expires = _jwtOptions.Expiration, refresh_token = validRefreshToken.RefreshTokenId, two_factor_auth_enabled = true, phone_number = user.PhoneNumber, email = user.Email, first_name = profile.FirstName, surname = profile.Surname }; var json = JsonConvert.SerializeObject(response, _serializerSettings); return(new OkObjectResult(json)); } } else { //create refresh token RefreshToken rt = new RefreshToken(); rt.StartDate = DateTime.UtcNow; DateTime dtmRefreshTokenEndDate = DateTime.UtcNow; dtmRefreshTokenEndDate = dtmRefreshTokenEndDate.AddMonths(6); rt.EndDate = dtmRefreshTokenEndDate; rt.IsEnabled = true; rt.UserId = identity.Claims.Single(c => c.Type == "id").Value; bool refreshTokenAdded = false; refreshTokenAdded = await _sqlServerUow.RefreshTokens.AddAsync(rt); // Serialize and return the response var response = new { id = user.Id, auth_token = await _jwtFactory.GenerateEncodedToken(user.UserName, identity), auth_token_valid = (int)_jwtOptions.ValidFor.TotalSeconds, auth_token_created = _jwtOptions.IssuedAt, auth_token_expires = _jwtOptions.Expiration, refresh_token = rt.RefreshTokenId, two_factor_auth_enabled = true, phone_number = user.PhoneNumber, email = user.Email, first_name = profile.FirstName, surname = profile.Surname }; var json = JsonConvert.SerializeObject(response, _serializerSettings); return(new OkObjectResult(json)); } } else if (result.IsLockedOut) { return(BadRequest(Errors.AddErrorToModelState("login_failure", "Locked out.", ModelState))); } else { return(BadRequest(Errors.AddErrorToModelState("login_failure", "Invalid authenticator code.", ModelState))); } }