Пример #1
0
        public async Task <ResourceOwner?> AuthenticateResourceOwner(
            string login,
            string password,
            CancellationToken cancellationToken)
        {
            var confirmationCode =
                await _confirmationCodeStore.Get(password, login, cancellationToken).ConfigureAwait(false);

            if (confirmationCode == null || confirmationCode.Subject != login)
            {
                return(null);
            }

            if (confirmationCode.IssueAt.AddSeconds(confirmationCode.ExpiresIn) <= DateTimeOffset.UtcNow)
            {
                return(null);
            }

            var resourceOwner = await _resourceOwnerRepository.GetResourceOwnerByClaim(
                OpenIdClaimTypes.PhoneNumber,
                login,
                cancellationToken)
                                .ConfigureAwait(false);

            if (resourceOwner != null)
            {
                await _confirmationCodeStore.Remove(password, resourceOwner.Subject !, cancellationToken)
                .ConfigureAwait(false);
            }

            return(resourceOwner);
        }
Пример #2
0
        public async Task <bool> Execute(string code, string subject, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(code))
            {
                return(false);
            }

            var confirmationCode = await _confirmationCodeStore.Get(code, subject, cancellationToken).ConfigureAwait(false);

            if (confirmationCode == null)
            {
                return(false);
            }

            var expirationDateTime = confirmationCode.IssueAt.AddSeconds(confirmationCode.ExpiresIn);

            if (DateTimeOffset.UtcNow < expirationDateTime)
            {
                return(true);
            }

            await _confirmationCodeStore.Remove(code, subject, cancellationToken).ConfigureAwait(false);

            return(false);
        }
Пример #3
0
        public async Task <ResourceOwner> AuthenticateResourceOwnerAsync(string login, string password)
        {
            if (string.IsNullOrWhiteSpace(login))
            {
                throw new ArgumentNullException(nameof(login));
            }

            if (string.IsNullOrWhiteSpace(password))
            {
                throw new ArgumentNullException(nameof(password));
            }

            var resourceOwner = await _resourceOwnerRepository.GetResourceOwnerByClaim(Core.Jwt.Constants.StandardResourceOwnerClaimNames.PhoneNumber, login).ConfigureAwait(false);

            if (resourceOwner == null)
            {
                return(null);
            }

            var confirmationCode = await _confirmationCodeStore.Get(password).ConfigureAwait(false);

            if (confirmationCode == null || confirmationCode.Subject != resourceOwner.Claims.First(c => c.Type == Core.Jwt.Constants.StandardResourceOwnerClaimNames.PhoneNumber).Value)
            {
                return(null);
            }

            if (confirmationCode.IssueAt.AddSeconds(confirmationCode.ExpiresIn) <= DateTime.UtcNow)
            {
                return(null);
            }

            await _confirmationCodeStore.Remove(password).ConfigureAwait(false);

            return(resourceOwner);
        }
Пример #4
0
        public Task <bool> Remove(string confirmationCode)
        {
            if (string.IsNullOrWhiteSpace(confirmationCode))
            {
                throw new ArgumentNullException(nameof(confirmationCode));
            }

            return(_confirmationCodeStore.Remove(confirmationCode));
        }
Пример #5
0
        public async Task <IActionResult> ConfirmCode(
            ConfirmCodeViewModel confirmCodeViewModel,
            CancellationToken cancellationToken)
        {
            if (confirmCodeViewModel == null)
            {
                throw new ArgumentNullException(nameof(confirmCodeViewModel));
            }

            var user = await SetUser().ConfigureAwait(false);

            if (user?.Identity != null && user.Identity.IsAuthenticated)
            {
                return(RedirectToAction("Index", "User", new { Area = "pwd" }));
            }

            var authenticatedUser = await _authenticationService
                                    .GetAuthenticatedUser(this, CookieNames.PasswordLessCookieName)
                                    .ConfigureAwait(false);

            if (authenticatedUser?.Identity == null || !authenticatedUser.Identity.IsAuthenticated)
            {
                var message = "SMS authentication cannot be performed";
                _logger.LogError(message);
                return(SetRedirection(message, Strings.InternalServerError, ErrorCodes.UnhandledExceptionCode));
            }

            var authenticatedUserClaims = authenticatedUser.Claims.ToArray();
            var subject     = authenticatedUserClaims.First(c => c.Type == OpenIdClaimTypes.Subject).Value;
            var phoneNumber = authenticatedUserClaims.First(c => c.Type == OpenIdClaimTypes.PhoneNumber);

            if (confirmCodeViewModel.Action == "resend") // Resend the confirmation code.
            {
                _ = await _generateAndSendSmsCodeOperation.Execute(phoneNumber.Value, cancellationToken)
                    .ConfigureAwait(false);

                return(Ok(confirmCodeViewModel));
            }

            // Check the confirmation code.
            if (confirmCodeViewModel.ConfirmationCode == null ||
                !await _validateConfirmationCode
                .Execute(confirmCodeViewModel.ConfirmationCode, subject, cancellationToken)
                .ConfigureAwait(false))
            {
                ModelState.AddModelError("message_error", "Confirmation code is not valid");
                return(Ok(confirmCodeViewModel));
            }

            await _authenticationService.SignOutAsync(
                HttpContext,
                CookieNames.PasswordLessCookieName,
                new AuthenticationProperties())
            .ConfigureAwait(false);

            var resourceOwnerOption =
                await _getUserOperation.Execute(authenticatedUser, cancellationToken).ConfigureAwait(false);

            if (resourceOwnerOption is Option <ResourceOwner> .Error e)
            {
                return(SetRedirection(e.Details.Detail, e.Details.Status.ToString(), e.Details.Title));
            }

            var resourceOwner = (resourceOwnerOption as Option <ResourceOwner> .Result) !.Item;

            if (!string.IsNullOrWhiteSpace(resourceOwner.TwoFactorAuthentication)) // Execute TWO Factor authentication
            {
                try
                {
                    await SetTwoFactorCookie(authenticatedUserClaims).ConfigureAwait(false);

                    await _generateAndSendSmsCodeOperation.Execute(phoneNumber.Value, cancellationToken)
                    .ConfigureAwait(false);

                    return(RedirectToAction("SendCode", new { code = confirmCodeViewModel.Code }));
                }
                catch (ClaimRequiredException)
                {
                    return(RedirectToAction("SendCode", new { code = confirmCodeViewModel.Code }));
                }
                catch (Exception)
                {
                    ModelState.AddModelError("message_error", "Two factor authenticator is not properly configured");
                    return(Ok(confirmCodeViewModel));
                }
            }

            if (!string.IsNullOrWhiteSpace(confirmCodeViewModel.Code)) // Execute OPENID workflow
            {
                var request = DataProtector.Unprotect <AuthorizationRequest>(confirmCodeViewModel.Code);
                await SetLocalCookie(authenticatedUserClaims, request.session_id !).ConfigureAwait(false);

                var issuerName   = Request.GetAbsoluteUriWithVirtualPath();
                var actionResult = await _authenticateHelper.ProcessRedirection(
                    request.ToParameter(),
                    confirmCodeViewModel.Code,
                    subject,
                    authenticatedUserClaims,
                    issuerName,
                    cancellationToken)
                                   .ConfigureAwait(false);

                var result = actionResult.CreateRedirectionFromActionResult(request, _logger);
                if (result != null)
                {
                    await LogAuthenticateUser(resourceOwner !.Subject !, actionResult.Amr !).ConfigureAwait(false);

                    return(result);
                }
            }

            await SetLocalCookie(authenticatedUserClaims, Id.Create())
            .ConfigureAwait(false);     // Authenticate the resource owner

            var modelCode = string.IsNullOrWhiteSpace(confirmCodeViewModel.Code)
                ? confirmCodeViewModel.ConfirmationCode
                : confirmCodeViewModel.Code;

            if (!string.IsNullOrWhiteSpace(modelCode))
            {
                await _confirmationCodeStore.Remove(modelCode, subject, cancellationToken).ConfigureAwait(false);
            }

            return(RedirectToAction("Index", "User", new { Area = "pwd" }));
        }