예제 #1
0
        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" }));
        }