/// <summary>
        /// Starts a refresh token request.
        /// </summary>
        /// <param name="refreshToken">The refresh token.</param>
        /// <returns>A refresh token result</returns>
        public async Task <RefreshTokenResult> RefreshTokenAsync(string refreshToken)
        {
            var client = await TokenClientFactory.CreateAsync(_options);

            var response = await client.RequestRefreshTokenAsync(refreshToken);

            if (response.IsError)
            {
                return(new RefreshTokenResult {
                    Error = response.Error
                });
            }

            // validate token response
            var validationResult = await _validator.ValidateTokenResponse(response, requireIdentityToken : false);

            if (!validationResult.Success)
            {
                return(new RefreshTokenResult {
                    Error = validationResult.Error
                });
            }

            return(new RefreshTokenResult
            {
                AccessToken = response.AccessToken,
                RefreshToken = response.RefreshToken,
                ExpiresIn = (int)response.ExpiresIn
            });
        }
        private async Task <TokenClient> GetTokenClientAsync()
        {
            if (_tokenClient == null)
            {
                _tokenClient = await TokenClientFactory.CreateAsync(_options);
            }

            return(_tokenClient);
        }
        private async Task <LoginResult> ProcessClaimsAsync(ResponseValidationResult result)
        {
            Logger.Debug("Processing claims");

            // get profile if enabled
            if (_options.LoadProfile)
            {
                Logger.Debug("load profile");

                var userInfoResult = await GetUserInfoAsync(result.TokenResponse.AccessToken);

                if (!userInfoResult.Success)
                {
                    return(new LoginResult(userInfoResult.Error));
                }

                Logger.Debug("profile claims:");
                Logger.LogClaims(userInfoResult.Claims);

                var primaryClaimTypes = result.Claims.Select(c => c.Type).Distinct();
                foreach (var claim in userInfoResult.Claims.Where(c => !primaryClaimTypes.Contains(c.Type)))
                {
                    result.Claims.Add(claim);
                }
            }
            else
            {
                Logger.Debug("don't load profile");
            }

            // success
            var loginResult = new LoginResult
            {
                Claims                = FilterClaims(result.Claims),
                AccessToken           = result.TokenResponse.AccessToken,
                RefreshToken          = result.TokenResponse.RefreshToken,
                AccessTokenExpiration = DateTime.Now.AddSeconds(result.TokenResponse.ExpiresIn),
                IdentityToken         = result.TokenResponse.IdentityToken,
                AuthenticationTime    = DateTime.Now
            };

            if (!string.IsNullOrWhiteSpace(result.TokenResponse.RefreshToken))
            {
                var providerInfo = await _options.GetProviderInformationAsync();

                loginResult.Handler = new RefeshTokenHandler(
                    await TokenClientFactory.CreateAsync(_options),
                    result.TokenResponse.RefreshToken,
                    result.TokenResponse.AccessToken);
            }

            return(loginResult);
        }