protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
        {
            var secret = new EsiaClientSecret(Options);

            Options.ClientSecret = secret.GenerateClientSecret();

            var queryStrings = new Dictionary <string, string>
            {
                { "response_type", "code" },
                { "client_id", Options.ClientId },
                { "redirect_uri", redirectUri },
                { "scope", secret.Scope },
                { "access_type", Options.AccessType },
                { "state", secret.State },
                { "client_secret", Options.ClientSecret },
                { "timestamp", secret.Timestamp },
            };

            var authorizationEndpoint = QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, queryStrings);

            return(authorizationEndpoint);
        }
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            var secret = new EsiaClientSecret(Options);

            Options.ClientSecret = secret.GenerateClientSecret();

            var requestParam = new Dictionary <string, string>
            {
                { "client_id", Options.ClientId },
                { "code", context.Code },
                { "grant_type", "authorization_code" },
                { "state", secret.State },
                { "scope", secret.Scope },
                { "timestamp", secret.Timestamp },
                { "token_type", "Bearer" },
                { "client_secret", Options.ClientSecret },
                { "redirect_uri", context.RedirectUri }
            };

            var request = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint);

            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            request.Content = new FormUrlEncodedContent(requestParam);

            var response = await Backchannel.SendAsync(request, Context.RequestAborted);

            if (response.IsSuccessStatusCode)
            {
                var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
                return(OAuthTokenResponse.Success(payload));
            }
            else
            {
                var error = "OAuth token endpoint failure: " + await Display(response);

                return(OAuthTokenResponse.Failed(new Exception(error)));
            }
        }