/// <summary>Underlying Async Authenticate method - might require to make external Http calls, hence making it Async</summary>
        /// <param name="authService">Authenticating Service</param>
        /// <param name="session">Authentication Session</param>
        /// <param name="request"></param>
        /// <returns></returns>
        private async Task <IHttpResult> AuthenticateAsync(IServiceBase authService, IAuthSession session, Authenticate request)
        {
            var tokens      = Init(authService, ref session, request);
            var httpRequest = authService.Request;

            var isInitialRequest = await IsInitialAuthenticateRequest(httpRequest, tokens).ConfigureAwait(false);

            // We need to get the user to login as we don't have any credentials for them
            if (isInitialRequest && !IsCallbackRequest(authService, request))
            {
                return(AuthenticateClient(authService, session, tokens, request.State, request.nonce));
            }

            // We've just returned from Identity Server so we need to get the tokens we've been given
            if (IsCallbackRequest(authService, request))
            {
                // If the tokens are not valid then redirect with an error
                var authTokens    = ParseAuthenticateTokens(httpRequest);
                var invalidTokens = AuthProviderSettings.AuthorizationFlow ==
                                    IdentityServerOpenIdAuthorizationFlowType.CodeFlow
                  ? authTokens.Code.IsNullOrEmpty()
                  : authTokens.IsEmpty || !IdTokenValidator.IsValidIdToken(tokens, authTokens.IdToken);


                if (invalidTokens)
                {
                    throw HttpError.Unauthorized(ErrorMessages.NotAuthenticated);
                }

                // Assign the Id token
                var idTokens = tokens as IdentityServerAuthTokens;
                if (idTokens != null)
                {
                    idTokens.IdToken = authTokens.IdToken;
                    idTokens.Code    = authTokens.Code;
                }

                var accessTokens = await AuthCodeClient.RequestCode(authTokens.Code, CallbackUrl)
                                   .ConfigureAwait(false);

                if (accessTokens != null)
                {
                    // Now we have the access token and the refresh token
                    tokens.AccessToken  = accessTokens.AccessToken;
                    tokens.RefreshToken = accessTokens.RefreshToken;
                }
            }

            session.IsAuthenticated = await IsValidAccessToken(tokens).ConfigureAwait(false);

            if (!session.IsAuthenticated)
            {
                throw HttpError.Unauthorized(ErrorMessages.NotAuthenticated);
            }
            return(OnAuthenticated(authService, session, tokens, new Dictionary <string, string>()));
        }
        public override async Task Init()
        {
            await base.Init().ConfigureAwait(false);

            if (AuthCodeClient == null)
            {
                AuthCodeClient = new AuthCodeClient(AuthProviderSettings);
            }

            if (IdTokenValidator == null)
            {
                IdTokenValidator = new IdentityServerIdTokenValidator(AuthProviderSettings);
                await IdTokenValidator.Init().ConfigureAwait(false);
            }
        }