public async Task <ActionResult> SendCode(CodeViewModel codeViewModel) { if (codeViewModel == null) { throw new ArgumentNullException(nameof(codeViewModel)); } await SetUser(); if (!ModelState.IsValid) { await TranslateView(DefaultLanguage); return(View(codeViewModel)); } // 1. Check user is authenticated var authenticatedUser = await _authenticationService.GetAuthenticatedUser(this, SimpleIdentityServer.Host.Constants.TwoFactorCookieName); if (authenticatedUser == null || authenticatedUser.Identity == null || !authenticatedUser.Identity.IsAuthenticated) { throw new IdentityServerException( SimpleIdentityServer.Core.Errors.ErrorCodes.UnhandledExceptionCode, SimpleIdentityServer.Core.Errors.ErrorDescriptions.TwoFactorAuthenticationCannotBePerformed); } // 2. Validate the code if (!await _authenticateActions.ValidateCode(codeViewModel.Code)) { await TranslateView(DefaultLanguage); ModelState.AddModelError("Code", "confirmation code is not valid"); _simpleIdentityServerEventSource.ConfirmationCodeNotValid(codeViewModel.Code); return(View(codeViewModel)); } // 3. Remove the code if (!await _authenticateActions.RemoveCode(codeViewModel.Code)) { await TranslateView(DefaultLanguage); ModelState.AddModelError("Code", "an error occured while trying to remove the code"); return(View(codeViewModel)); } // 4. Authenticate the resource owner await _authenticationService.SignOutAsync(HttpContext, SimpleIdentityServer.Host.Constants.TwoFactorCookieName, new Microsoft.AspNetCore.Authentication.AuthenticationProperties()); await SetLocalCookie(authenticatedUser.Claims, Guid.NewGuid().ToString()); return(RedirectToAction("Index", "User")); }
public async Task <ActionResult> SendCode(CodeViewModel codeViewModel) { if (codeViewModel == null) { throw new ArgumentNullException(nameof(codeViewModel)); } ViewBag.IsAuthenticated = false; codeViewModel.Validate(ModelState); if (!ModelState.IsValid) { await TranslateView(DefaultLanguage).ConfigureAwait(false); return(View(codeViewModel)); } // 1. Check user is authenticated var authenticatedUser = await _authenticationService.GetAuthenticatedUser(this, Host.Constants.CookieNames.TwoFactorCookieName).ConfigureAwait(false); if (authenticatedUser == null || authenticatedUser.Identity == null || !authenticatedUser.Identity.IsAuthenticated) { throw new IdentityServerException(ErrorCodes.UnhandledExceptionCode, ErrorDescriptions.TwoFactorAuthenticationCannotBePerformed); } // 2. Resend the confirmation code. if (codeViewModel.Action == CodeViewModel.RESEND_ACTION) { await TranslateView(DefaultLanguage).ConfigureAwait(false); var resourceOwner = await _userActions.GetUser(authenticatedUser).ConfigureAwait(false); var claim = resourceOwner.Claims.FirstOrDefault(c => c.Type == codeViewModel.ClaimName); if (claim != null) { resourceOwner.Claims.Remove(claim); } resourceOwner.Claims.Add(new Claim(codeViewModel.ClaimName, codeViewModel.ClaimValue)); var claimsLst = resourceOwner.Claims.Select(c => new ClaimAggregate(c.Type, c.Value)); await _userActions.UpdateClaims(authenticatedUser.GetSubject(), claimsLst).ConfigureAwait(false); string code; try { code = await _authenticateActions.GenerateAndSendCode(authenticatedUser.GetSubject()).ConfigureAwait(false); _simpleIdentityServerEventSource.GetConfirmationCode(code); } catch { ModelState.AddModelError("message_error", "An internal error occured while trying to send the confirmation code"); } return(View(codeViewModel)); } // 3. Validate the confirmation code if (!await _authenticateActions.ValidateCode(codeViewModel.Code).ConfigureAwait(false)) { await TranslateView(DefaultLanguage).ConfigureAwait(false); ModelState.AddModelError("Code", "confirmation code is not valid"); _simpleIdentityServerEventSource.ConfirmationCodeNotValid(codeViewModel.Code); return(View(codeViewModel)); } // 4. Remove the code if (!await _authenticateActions.RemoveCode(codeViewModel.Code).ConfigureAwait(false)) { await TranslateView(DefaultLanguage).ConfigureAwait(false); ModelState.AddModelError("Code", "an error occured while trying to remove the code"); return(View(codeViewModel)); } // 5. Authenticate the resource owner await _authenticationService.SignOutAsync(HttpContext, Host.Constants.CookieNames.TwoFactorCookieName, new AuthenticationProperties()).ConfigureAwait(false); // 6. Redirect the user agent if (!string.IsNullOrWhiteSpace(codeViewModel.AuthRequestCode)) { var request = _dataProtector.Unprotect <AuthorizationRequest>(codeViewModel.AuthRequestCode); await SetLocalCookie(authenticatedUser.Claims, request.SessionId).ConfigureAwait(false); var issuerName = Request.GetAbsoluteUriWithVirtualPath(); var actionResult = await _authenticateHelper.ProcessRedirection(request.ToParameter(), codeViewModel.AuthRequestCode, authenticatedUser.GetSubject(), authenticatedUser.Claims.ToList(), issuerName).ConfigureAwait(false); LogAuthenticateUser(actionResult, request.ProcessId); var result = this.CreateRedirectionFromActionResult(actionResult, request); return(result); } else { await SetLocalCookie(authenticatedUser.Claims, Guid.NewGuid().ToString()).ConfigureAwait(false); } // 7. Redirect the user agent to the User view. return(RedirectToAction("Index", "User", new { area = "UserManagement" })); }