protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <StartRequest> input,
                                                                               CacheItem relatedItem)
        {
            var wasContinued = CheckIfContinued(input, relatedItem);
            var composeInfo  = new BaseJwtComposeInfo(input)
            {
                Behavior         = GetNextBehaviorFunc(input, relatedItem),
                IncludeRequester = true
            };

            var jwt = JwtComposer.GenerateBaseStepJwt(composeInfo, IdentitiesProvider.GenerateUserId());

            if (!wasContinued)
            {
                await StartFlowCommand.ExecuteAsync(new StartFlowCommand.Input
                {
                    Context                    = input.Context,
                    ResponseJwt                = jwt,
                    CredIdCookieValue          = input.Data.CredId,
                    EncryptionTokenCookieValue = input.Data.EncryptionToken,
                    RecoveryTokenCookieValue   = input.Data.RecoveryToken,
                    RequestToken               = input.RequestToken
                });
            }

            return(new JwtContainer
            {
                Jwt = jwt
            });
        }
        protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <JwtContainer> input,
                                                                               CacheItem relatedItem)
        {
            var userData = _jwtService.GetDataFromJwt <UserIdentitiesData>(input.Data.Jwt).Data;

            relatedItem.AuthCookieType = CookieType.Passcode;

            await _savePartialConnectionCommand.ExecuteAsync(userData, relatedItem);

            await _userHandlerAdapter.UpgradeConnectionAsync(userData.PublicKey, new OwnIdConnection
            {
                AuthType      = ConnectionAuthType.Passcode,
                PublicKey     = userData.PublicKey,
                RecoveryData  = userData.RecoveryData,
                RecoveryToken = relatedItem.RecoveryToken
            });

            var composeInfo = new BaseJwtComposeInfo(input)
            {
                Behavior = GetNextBehaviorFunc(input, relatedItem)
            };
            var jwt = JwtComposer.GenerateFinalStepJwt(composeInfo);

            return(new StateResult(jwt, _cookieService.CreateAuthCookies(relatedItem)));
        }
Пример #3
0
        protected override Task <ITransitionResult> ExecuteInternalAsync(TransitionInput input, CacheItem relatedItem)
        {
            var composeInfo = new BaseJwtComposeInfo(input);

            string jwt;

            if (relatedItem.Status == CacheItemStatus.Approved)
            {
                composeInfo.Behavior = GetNextBehaviorFunc(input, relatedItem);
                jwt = JwtComposer.GenerateBaseStepJwt(composeInfo);
            }
            else
            {
                composeInfo.Behavior = new FrontendBehavior
                {
                    Type          = StepType.Declined,
                    ChallengeType = relatedItem.ChallengeType,
                    ActionType    = ActionType.Finish
                };

                jwt = JwtComposer.GenerateFinalStepJwt(composeInfo);
            }

            return(Task.FromResult(new GetApprovalStatusResponse(jwt, relatedItem.Status) as ITransitionResult));
        }
Пример #4
0
        protected StateResult GenerateResult(TransitionInput <string> input, CacheItem relatedItem)
        {
            var composeInfo = new BaseJwtComposeInfo(input)
            {
                Behavior = GetNextBehaviorFunc(input, relatedItem),
            };

            var jwt = JwtComposer.GenerateBaseStepJwt(composeInfo, relatedItem.DID);

            //TODO: add remove other cookies
            return(new StateResult(jwt, _cookieService.CreateAuthCookies(relatedItem)));
        }
Пример #5
0
        protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput input,
                                                                               CacheItem relatedItem)
        {
            await _stopFlowCommand.ExecuteAsync(input.Context, "Error_UserCanceledAuth");

            var composeInfo = new BaseJwtComposeInfo(input)
            {
                Behavior = GetNextBehaviorFunc(input, relatedItem),
            };

            return(new JwtContainer(JwtComposer.GenerateFinalStepJwt(composeInfo)));
        }
        protected override async Task<ITransitionResult> ExecuteInternalAsync(TransitionInput<JwtContainer> input,
            CacheItem relatedItem)
        {
            relatedItem = await _linkAccountCommand.ExecuteAsync(input.Data, relatedItem);

            var composeInfo = new BaseJwtComposeInfo(input)
            {
                Behavior = GetNextBehaviorFunc(input, relatedItem),
            };

            // TODO: change to generic step generation
            var jwt = JwtComposer.GenerateFinalStepJwt(composeInfo);
            return new StateResult(jwt, _cookieService.CreateAuthCookies(relatedItem));
        }
Пример #7
0
        private async Task <ITransitionResult> FinishAuthProcessAsync(UserIdentitiesData userData, CacheItem relatedItem,
                                                                      TransitionInput <JwtContainer> input)
        {
            await _savePartialConnectionCommand.ExecuteAsync(userData, relatedItem);

            var composeInfo = new BaseJwtComposeInfo(input)
            {
                Behavior = FrontendBehavior.CreateSuccessFinish(relatedItem.ChallengeType)
            };

            var jwt = JwtComposer.GenerateFinalStepJwt(composeInfo);

            return(new StateResult(jwt, _cookieService.CreateAuthCookies(relatedItem)));
        }
        protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <JwtContainer> input,
                                                                               CacheItem relatedItem)
        {
            var userData = _jwtService.GetDataFromJwt <UserIdentitiesData>(input.Data.Jwt).Data;

            await _savePartialConnectionCommand.ExecuteAsync(userData, relatedItem);

            var composeInfo = new BaseJwtComposeInfo(input)
            {
                Behavior = GetNextBehaviorFunc(input, relatedItem),
            };
            var jwt = JwtComposer.GenerateFinalStepJwt(composeInfo);

            return(new StateResult(jwt, _cookieService.CreateAuthCookies(relatedItem)));
        }
        protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput input,
                                                                               CacheItem relatedItem)
        {
            var result = await _internalConnectionRecoveryCommand.ExecuteAsync(relatedItem.RequestToken);

            var composeInfo = new BaseJwtComposeInfo(input)
            {
                Behavior  = GetNextBehaviorFunc(input, relatedItem),
                EncKey    = relatedItem.EncKey,
                EncVector = relatedItem.EncVector
            };

            var jwt = JwtComposer.GenerateRecoveryDataJwt(composeInfo, result);

            return(new JwtContainer(jwt));
        }
Пример #10
0
        private async Task <ITransitionResult> SwitchConnectionAuthTypeAsync(CacheItem relatedItem,
                                                                             TransitionInput <JwtContainer> input, bool supportsFido2, string publicKey)
        {
            relatedItem.NewAuthType
                = supportsFido2 && _configuration.Fido2.IsEnabled
                    ? ConnectionAuthType.Fido2
                    : ConnectionAuthType.Passcode;

            var composeInfo = new BaseJwtComposeInfo(input)
            {
                EncKey    = relatedItem.EncKey,
                EncVector = relatedItem.EncVector
            };

            switch (relatedItem.NewAuthType)
            {
            case ConnectionAuthType.Passcode:
                composeInfo.Behavior = new FrontendBehavior(StepType.EnterPasscode, relatedItem.ChallengeType,
                                                            GetNextBehaviorFunc(input, relatedItem))
                {
                    AlternativeBehavior = new FrontendBehavior(StepType.ResetPasscode, relatedItem.ChallengeType,
                                                               new CallAction(UrlProvider.GetResetPasscodeUrl(relatedItem.Context),
                                                                              HttpMethod.Delete.ToString()))
                };
                break;

            case ConnectionAuthType.Fido2:
            {
                await _cacheItemRepository.UpdateAsync(relatedItem.Context, item => item.OldPublicKey = publicKey);

                var fido2Url = UrlProvider.GetFido2Url(relatedItem.Context, relatedItem.RequestToken,
                                                       input.CultureInfo?.Name);
                composeInfo.Behavior = FrontendBehavior.CreateRedirect(fido2Url);
                break;
            }

            default:
                throw new ArgumentOutOfRangeException();
            }

            var jwt = JwtComposer.GenerateBaseStepJwt(composeInfo);

            return(new StateResult(jwt, _cookieService.CreateAuthCookies(relatedItem)));
        }
Пример #11
0
        protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <UserIdentification> input,
                                                                               CacheItem relatedItem)
        {
            var result = await _checkUserExistenceCommand.ExecuteAsync(input.Data);

            if (result)
            {
                throw new OwnIdException(ErrorType.UserAlreadyExists);
            }

            var composeInfo = new BaseJwtComposeInfo(input)
            {
                Behavior = GetNextBehaviorFunc(input, relatedItem)
            };

            var jwt = JwtComposer.GenerateBaseStepJwt(composeInfo);

            return(new JwtContainer(jwt));
        }
        protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <AcceptStartRequest> input,
                                                                               CacheItem relatedItem)
        {
            var composeInfo = new BaseJwtComposeInfo(input)
            {
                IncludeFido2FallbackBehavior = true
            };

            if (input.Data.AuthType.HasValue)
            {
                switch (input.Data.AuthType)
                {
                case ConnectionAuthType.Basic:
                    if (String.IsNullOrEmpty(input.Data.ExtAuthPayload))
                    {
                        composeInfo.Behavior = GetNextBehaviorFunc(input, relatedItem);
                    }
                    else
                    {
                        composeInfo.Behavior = new FrontendBehavior(StepType.UpgradeToFido2, ChallengeType.Login,
                                                                    new CallAction(UrlProvider.GetSwitchAuthTypeUrl(relatedItem.Context,
                                                                                                                    ConnectionAuthType.Fido2)));
                    }
                    break;

                case ConnectionAuthType.Passcode:
                    composeInfo.Behavior = NavigateToEnterPasscode(input, relatedItem);
                    break;

                case ConnectionAuthType.Fido2:
                    if (string.IsNullOrEmpty(input.Data.ExtAuthPayload))
                    {
                        composeInfo.Behavior = await NavigateToPasswordlessPageAsync(input, relatedItem);
                    }
                    else
                    {
                        var switchResult =
                            await _trySwitchToFido2FlowCommand.ExecuteAsync(relatedItem, input.Data.ExtAuthPayload);

                        if (switchResult == null &&
                            _coreConfiguration.Fido2FallbackBehavior == Fido2FallbackBehavior.Block)
                        {
                            return(CreateErrorResponse(input, ErrorType.RequiresBiometricInput));
                        }

                        composeInfo.Behavior = switchResult ?? GetNextBehaviorFunc(input, relatedItem);
                    }

                    return(new JwtContainer(JwtComposer.GenerateBaseStepJwt(composeInfo)));

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            else if (_coreConfiguration.TFAEnabled)
            {
                if (input.Data.SupportsFido2 && _coreConfiguration.Fido2.IsEnabled)
                {
                    // check if fido2 page response available
                    if (string.IsNullOrWhiteSpace(input.Data.ExtAuthPayload))
                    {
                        composeInfo.Behavior = await NavigateToPasswordlessPageAsync(input, relatedItem);
                    }
                    else
                    {
                        var switchResult =
                            await _trySwitchToFido2FlowCommand.ExecuteAsync(relatedItem, input.Data.ExtAuthPayload);

                        if (switchResult == null &&
                            _coreConfiguration.Fido2FallbackBehavior == Fido2FallbackBehavior.Block)
                        {
                            return(CreateErrorResponse(input, ErrorType.RequiresBiometricInput));
                        }

                        composeInfo.Behavior = switchResult ?? GetNextBehaviorFunc(input, relatedItem);
                    }

                    return(new JwtContainer(JwtComposer.GenerateBaseStepJwt(composeInfo)));
                }

                // if FIDO2 flow or there is no way to login (with/without recovery with previously created creds)
                if (relatedItem.IsFido2Flow ||
                    _coreConfiguration.Fido2FallbackBehavior == Fido2FallbackBehavior.Block &&
                    relatedItem.ChallengeType != ChallengeType.Login && (!input.Data.AuthType.HasValue ||
                                                                         !string.IsNullOrEmpty(relatedItem
                                                                                               .RecoveryToken)))
                {
                    return(CreateErrorResponse(input, ErrorType.RequiresBiometricInput));
                }

                // go to passcode if such behavior enabled and check if create
                if (_coreConfiguration.Fido2FallbackBehavior == Fido2FallbackBehavior.Passcode &&
                    (relatedItem.AuthCookieType == CookieType.Passcode ||
                     relatedItem.ChallengeType != ChallengeType.Login))
                {
                    composeInfo.Behavior = NavigateToEnterPasscode(input, relatedItem);
                }
            }

            if (composeInfo.Behavior == null && (!_coreConfiguration.TFAEnabled ||
                                                 _coreConfiguration.Fido2FallbackBehavior
                                                 == Fido2FallbackBehavior.Basic))
            {
                composeInfo.Behavior = GetNextBehaviorFunc(input, relatedItem);
            }

            if (!string.IsNullOrWhiteSpace(relatedItem.EncKey))
            {
                composeInfo.EncKey    = relatedItem.EncKey;
                composeInfo.EncVector = relatedItem.EncVector;
            }
            else
            {
                var updatedItem = await _setNewEncryptionTokenCommand.ExecuteAsync(relatedItem.Context);

                composeInfo.EncKey    = updatedItem.EncKey;
                composeInfo.EncVector = updatedItem.EncVector;
                // TODO: rework
                relatedItem = updatedItem;
            }

            composeInfo.CanBeRecovered = !string.IsNullOrEmpty(relatedItem.RecoveryToken);

            return(new JwtContainer(JwtComposer.GenerateBaseStepJwt(composeInfo,
                                                                    relatedItem.DID ?? _identitiesProvider.GenerateUserId())));
        }