/// <summary>
        /// 通过Code获取Access Token(这是第二步)
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            string address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary <string, string>()
            {
                ["appid"]      = Options.ClientId,
                ["secret"]     = Options.ClientSecret,
                ["code"]       = context.Code,
                ["grant_type"] = "authorization_code"
            });

            using var response = await Backchannel.GetAsync(address, Context.RequestAborted);

            var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());

            if (!string.IsNullOrEmpty(payload.RootElement.GetString("errcode")))
            {
                Logger.LogError("An error occurred while retrieving an access token: the remote server " +
                                "returned a {Status} response with the following payload: {Headers} {Body}.",
                                /* Status: */ response.StatusCode,
                                /* Headers: */ response.Headers.ToString(),
                                /* Body: */ await response.Content.ReadAsStringAsync());

                return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
            }
            return(OAuthTokenResponse.Success(payload));
        }
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            var tokenRequestParams = new Dictionary <string, string>()
            {
                { "redirect_uri", context.RedirectUri },
                { "code", context.Code },
                { "grant_type", "authorization_code" },
            };

            var requestContent = new FormUrlEncodedContent(tokenRequestParams);

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

            requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{this.Options.ClientId}:{this.Options.ClientSecret}")));
            requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            requestMessage.Content = requestContent;
            var response = await this.Backchannel.SendAsync(requestMessage, this.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)));
            }
        }
Example #3
0
    protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
    {
        // See https://open.work.weixin.qq.com/api/doc/90000/90135/91039 for details.
        var tokenRequestParameters = new Dictionary <string, string?>()
        {
            ["corpid"]     = Options.ClientId,
            ["corpsecret"] = Options.ClientSecret,
        };

        // PKCE https://tools.ietf.org/html/rfc7636#section-4.5, see BuildChallengeUrl
        if (context.Properties.Items.TryGetValue(OAuthConstants.CodeVerifierKey, out var codeVerifier))
        {
            tokenRequestParameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier !);
            context.Properties.Items.Remove(OAuthConstants.CodeVerifierKey);
        }

        var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, tokenRequestParameters);

        using var response = await Backchannel.GetAsync(address, Context.RequestAborted);

        if (!response.IsSuccessStatusCode)
        {
            await Log.ExchangeCodeErrorAsync(Logger, response, Context.RequestAborted);

            return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
        }

        var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted));

        return(OAuthTokenResponse.Success(payload));
    }
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
        {
            // See https://open.work.weixin.qq.com/api/doc/90000/90135/91039 for details.
            string address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary <string, string?>()
            {
                ["corpid"]     = Options.ClientId,
                ["corpsecret"] = Options.ClientSecret,
            });

            using var response = await Backchannel.GetAsync(address, Context.RequestAborted);

            if (!response.IsSuccessStatusCode)
            {
                Logger.LogError("An error occurred while retrieving an access token: the remote server " +
                                "returned a {Status} response with the following payload: {Headers} {Body}.",
                                /* Status: */ response.StatusCode,
                                /* Headers: */ response.Headers.ToString(),
                                /* Body: */ await response.Content.ReadAsStringAsync(Context.RequestAborted));

                return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
            }

            var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted));

            return(OAuthTokenResponse.Success(payload));
        }
Example #5
0
        /// <summary>
        /// 通过Code获取Access Token(这是第二步)
        /// </summary>
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            var code        = context.Code;
            var redirectUri = context.RedirectUri;
            var parameters  = new Dictionary <string, string>
            {
                { "appid", Options.ClientId },
                { "secret", Options.ClientSecret },
                { "code", code },
                { "grant_type", "authorization_code" }
            };

            var endpoint = QueryHelpers.AddQueryString(Options.TokenEndpoint, parameters);

            var response = await Backchannel.GetAsync(endpoint, Context.RequestAborted);

            if (response.IsSuccessStatusCode)
            {
                var payloadText = await response.Content.ReadAsStringAsync();

                var payload = JsonDocument.Parse(payloadText);
                return(OAuthTokenResponse.Success(payload));
            }
            else
            {
                return(OAuthTokenResponse.Failed(new Exception("获取微信AccessToken出错。")));
            }
        }
Example #6
0
    protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
    {
        var tokenRequestParameters = new Dictionary <string, string?>()
        {
            ["app_id"] = Options.ClientId,
            ["secret"] = Options.ClientSecret,
            ["code"]   = context.Code,
            ["output"] = "json",
        };

        // PKCE https://tools.ietf.org/html/rfc7636#section-4.5, see BuildChallengeUrl
        if (context.Properties.Items.TryGetValue(OAuthConstants.CodeVerifierKey, out var codeVerifier))
        {
            tokenRequestParameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier);
            context.Properties.Items.Remove(OAuthConstants.CodeVerifierKey);
        }

        var endpoint = QueryHelpers.AddQueryString(Options.TokenEndpoint, tokenRequestParameters);

        using var requestMessage = new HttpRequestMessage(HttpMethod.Get, endpoint);
        requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json));
        using var response = await Backchannel.SendAsync(requestMessage, Context.RequestAborted);

        if (!response.IsSuccessStatusCode)
        {
            await Log.ExchangeCodeErrorAsync(Logger, response, Context.RequestAborted);

            return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an OAuth token.")));
        }

        var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted));

        return(OAuthTokenResponse.Success(payload));
    }
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
        {
            string address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary <string, string>
            {
                ["app_id"]       = Options.ClientId,
                ["app_secret"]   = Options.ClientSecret,
                ["code"]         = context.Code,
                ["redirect_uri"] = context.RedirectUri
            });

            using var request  = new HttpRequestMessage(HttpMethod.Get, address);
            using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted);

            if (!response.IsSuccessStatusCode)
            {
                Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
                                "returned a {Status} response with the following payload: {Headers} {Body}.",
                                /* Status: */ response.StatusCode,
                                /* Headers: */ response.Headers.ToString(),
                                /* Body: */ await response.Content.ReadAsStringAsync());

                throw new HttpRequestException("An error occurred while retrieving the user profile.");
            }

            var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());

            return(OAuthTokenResponse.Success(payload));
        }
    protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
    {
        // See https://wiki.connect.qq.com/%E4%BD%BF%E7%94%A8authorization_code%E8%8E%B7%E5%8F%96access_token for details
        string address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary <string, string?>(6)
        {
            ["client_id"]     = Options.ClientId,
            ["client_secret"] = Options.ClientSecret,
            ["redirect_uri"]  = context.RedirectUri,
            ["code"]          = context.Code,
            ["grant_type"]    = "authorization_code",
            ["fmt"]           = "json" // Return JSON instead of x-www-form-urlencoded which is default due to historical reasons
        });

        using var request = new HttpRequestMessage(HttpMethod.Get, address);

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

        if (!response.IsSuccessStatusCode)
        {
            await Log.ExchangeCodeErrorAsync(Logger, response, Context.RequestAborted);

            return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
        }

        using var stream = await response.Content.ReadAsStreamAsync(Context.RequestAborted);

        var payload = JsonDocument.Parse(stream);

        return(OAuthTokenResponse.Success(payload));
    }
Example #9
0
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            var parameters = new Dictionary <string, string>()
            {
                { "client_id", Options.ClientId },
                { "client_secret", Options.ClientSecret },
                { "redirect_uri", context.RedirectUri },
                { "grant_type", "authorization_code" },
                { "code", context.Code },
                { "scope", string.Join(" ", Options.Scope) }
            };

            var requestMessage = new HttpRequestMessage(HttpMethod.Post, QueryHelpers.AddQueryString(Options.TokenEndpoint, parameters));

            requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

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

            if (response.IsSuccessStatusCode)
            {
                string body    = new StreamReader(await response.Content.ReadAsStreamAsync()).ReadToEnd(); // TODO merge into next line
                var    payload = JsonDocument.Parse(body);
                return(OAuthTokenResponse.Success(payload));
            }
            else
            {
                var error = "OAuth token endpoint failure: " + await Display(response);

                return(OAuthTokenResponse.Failed(new Exception(error)));
            }
        }
Example #10
0
        /// <summary>
        /// 通过Code获取Access Token(这是第二步)
        /// </summary>
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            var parameters = new Dictionary <string, string>
            {
                { "appid", Options.ClientId },
                { "secret", Options.ClientSecret },
                { "code", context.Code },
                { "grant_type", "authorization_code" }
            };

            _logger.LogDebug("code换取access_token");
            var endpoint = QueryHelpers.AddQueryString(Options.TokenEndpoint, parameters);

            _logger.LogDebug(endpoint);
            var response = await Backchannel.GetAsync(endpoint, Context.RequestAborted);

            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsStringAsync();

                _logger.LogDebug(result);
                var payload = JsonDocument.Parse(result);
                if (payload.RootElement.TryGetProperty("errcode", out JsonElement errcode))
                {
                    return(OAuthTokenResponse.Failed(new Exception($"获取微信AccessToken出错。{errcode}")));
                }
                return(OAuthTokenResponse.Success(payload));
            }
            else
            {
                return(OAuthTokenResponse.Failed(new Exception("获取微信AccessToken出错。")));
            }
        }
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
        {
            using var request = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint)
                  {
                      Content = new FormUrlEncodedContent(new Dictionary <string, string>
                {
                    ["client_id"]     = Options.ClientId,
                    ["redirect_uri"]  = context.RedirectUri,
                    ["client_secret"] = Options.ClientSecret,
                    ["code"]          = context.Code,
                    ["grant_type"]    = "authorization_code"
                })
                  };

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

            if (!response.IsSuccessStatusCode)
            {
                Logger.LogError("An error occurred while retrieving an access token: the remote server " +
                                "returned a {Status} response with the following payload: {Headers} {Body}.",
                                /* Status: */ response.StatusCode,
                                /* Headers: */ response.Headers.ToString(),
                                /* Body: */ await response.Content.ReadAsStringAsync());

                return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
            }

            // Note: StackExchange's token endpoint doesn't return JSON but uses application/x-www-form-urlencoded.
            // Since OAuthTokenResponse expects a JSON payload, a response is manually created using the returned values.
            var content = QueryHelpers.ParseQuery(await response.Content.ReadAsStringAsync());

            var copy = await CopyPayloadAsync(content);

            return(OAuthTokenResponse.Success(copy));
        }
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            using var request = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint);
            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));

            var parameters = new Dictionary <string, string>
            {
                ["grant_type"]    = "authorization_code",
                ["redirect_uri"]  = Options.RederectUrl,
                ["code"]          = context.Code,
                ["client_id"]     = Options.ClientId,
                ["client_secret"] = Options.ClientSecret
            };

            request.Content = new FormUrlEncodedContent(parameters !);

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

            if (!response.IsSuccessStatusCode)
            {
                return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
            }
            var httpContent = await response.Content.ReadAsStringAsync();

            var tokenInfo = JsonConvert.DeserializeObject <dynamic>(httpContent);

            tokenInfo["subject"] = context.Code;
            var payload = JsonDocument.Parse(JsonConvert.SerializeObject(tokenInfo));

            return(OAuthTokenResponse.Success(payload));
        }
Example #13
0
    /// <summary>
    /// Exchanges the authorization code for a authorization token from the remote provider.
    /// </summary>
    /// <param name="context">The <see cref="OAuthCodeExchangeContext"/>.</param>
    /// <returns>The response <see cref="OAuthTokenResponse"/>.</returns>
    protected virtual async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
    {
        var tokenRequestParameters = new Dictionary <string, string>()
        {
            { "client_id", Options.ClientId },
            { "redirect_uri", context.RedirectUri },
            { "client_secret", Options.ClientSecret },
            { "code", context.Code },
            { "grant_type", "authorization_code" },
        };

        // PKCE https://tools.ietf.org/html/rfc7636#section-4.5, see BuildChallengeUrl
        if (context.Properties.Items.TryGetValue(OAuthConstants.CodeVerifierKey, out var codeVerifier))
        {
            tokenRequestParameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier !);
            context.Properties.Items.Remove(OAuthConstants.CodeVerifierKey);
        }

        var requestContent = new FormUrlEncodedContent(tokenRequestParameters !);

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

        requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        requestMessage.Content = requestContent;
        requestMessage.Version = Backchannel.DefaultRequestVersion;
        var response = await Backchannel.SendAsync(requestMessage, Context.RequestAborted);

        var body = await response.Content.ReadAsStringAsync();

        return(response.IsSuccessStatusCode switch
        {
            true => OAuthTokenResponse.Success(JsonDocument.Parse(body)),
            false => PrepareFailedOAuthTokenReponse(response, body)
        });
Example #14
0
    protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
    {
        using var request = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint);
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));

        var parameters = new Dictionary <string, string>
        {
            ["redirect_uri"]          = context.RedirectUri,
            ["client_assertion"]      = Options.ClientSecret,
            ["assertion"]             = context.Code,
            ["grant_type"]            = "urn:ietf:params:oauth:grant-type:jwt-bearer",
            ["client_assertion_type"] = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
        };

        request.Content = new FormUrlEncodedContent(parameters !);

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

        if (!response.IsSuccessStatusCode)
        {
            await Log.ExchangeCodeErrorAsync(Logger, response, Context.RequestAborted);

            return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
        }

        var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted));

        return(OAuthTokenResponse.Success(payload));
    }
    protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
    {
        string address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary <string, string?>()
        {
            ["appid"]      = Options.ClientId,
            ["secret"]     = Options.ClientSecret,
            ["code"]       = context.Code,
            ["grant_type"] = "authorization_code"
        });

        using var response = await Backchannel.GetAsync(address);

        if (!response.IsSuccessStatusCode)
        {
            await Log.ExchangeCodeErrorAsync(Logger, response, Context.RequestAborted);

            return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
        }

        var json = await response.Content.ReadAsStringAsync(Context.RequestAborted);

        var payload = JsonDocument.Parse(json);

        var errorCode = payload.RootElement.GetString("errcode");

        if (!string.IsNullOrEmpty(errorCode))
        {
            Log.ExchangeCodeErrorCode(Logger, errorCode, response.Headers.ToString(), json);
            return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
        }

        return(OAuthTokenResponse.Success(payload));
    }
Example #16
0
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
        {
            string address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary <string, string>()
            {
                ["client_id"]     = Options.ClientId,
                ["client_secret"] = Options.ClientSecret,
                ["redirect_uri"]  = context.RedirectUri,
                ["code"]          = context.Code,
                ["grant_type"]    = "authorization_code",
            });

            using var request = new HttpRequestMessage(HttpMethod.Get, address);

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

            if (!response.IsSuccessStatusCode)
            {
                Logger.LogError("An error occurred while retrieving an access token: the remote server " +
                                "returned a {Status} response with the following payload: {Headers} {Body}.",
                                /* Status: */ response.StatusCode,
                                /* Headers: */ response.Headers.ToString(),
                                /* Body: */ await response.Content.ReadAsStringAsync());

                return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
            }

            var content = QueryHelpers.ParseQuery(await response.Content.ReadAsStringAsync());
            var payload = await CopyPayloadAsync(content);

            return(OAuthTokenResponse.Success(payload));
        }
Example #17
0
    protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
    {
        var tokenRequestParameters = new Dictionary <string, string>
        {
            ["grant_type"]    = "authorization_code",
            ["code"]          = context.Code,
            ["redirect_uri"]  = context.RedirectUri,
            ["client_id"]     = Options.ClientId,
            ["client_secret"] = Options.ClientSecret,
        };

        // PKCE https://tools.ietf.org/html/rfc7636#section-4.5, see BuildChallengeUrl
        if (context.Properties.Items.TryGetValue(OAuthConstants.CodeVerifierKey, out var codeVerifier))
        {
            tokenRequestParameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier !);
            context.Properties.Items.Remove(OAuthConstants.CodeVerifierKey);
        }

        using var request = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint);
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        request.Content = new FormUrlEncodedContent(tokenRequestParameters);

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

        if (!response.IsSuccessStatusCode)
        {
            await Log.ExchangeCodeErrorAsync(Logger, response, Context.RequestAborted);

            return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
        }

        var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted));

        return(OAuthTokenResponse.Success(payload));
    }
Example #18
0
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
        {
            using var request = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint);
            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var parameters = new Dictionary <string, string>
            {
                ["grant_type"]    = "authorization_code",
                ["code"]          = context.Code,
                ["redirect_uri"]  = context.RedirectUri,
                ["client_id"]     = Options.ClientId,
                ["client_secret"] = Options.ClientSecret
            };

            request.Content = new FormUrlEncodedContent(parameters !);

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

            if (!response.IsSuccessStatusCode)
            {
                Logger.LogError("An error occurred while retrieving an access token: the remote server " +
                                "returned a {Status} response with the following payload: {Headers} {Body}.",
                                /* Status: */ response.StatusCode,
                                /* Headers: */ response.Headers.ToString(),
                                /* Body: */ await response.Content.ReadAsStringAsync(Context.RequestAborted));

                return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
            }

            var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted));

            return(OAuthTokenResponse.Success(payload));
        }
Example #19
0
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            var tokenRequestParameters = new List <KeyValuePair <string, string> >
            {
                new KeyValuePair <string, string>("appid", Options.ClientId),
                new KeyValuePair <string, string>("secret", Options.ClientSecret),
                new KeyValuePair <string, string>("code", context.Code),
                new KeyValuePair <string, string>("grant_type", "authorization_code"),
            };

            var urlEncodedContent = new FormUrlEncodedContent(tokenRequestParameters);

            var response =
                await Backchannel.PostAsync(Options.TokenEndpoint, urlEncodedContent, Context.RequestAborted);

            //var response = await Backchannel.SendAsync(new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint)
            //{
            //    Headers = {
            //        Accept = {
            //            new MediaTypeWithQualityHeaderValue("application/json")
            //        }
            //    },
            //    Content = urlEncodedContent
            //}, Context.RequestAborted);

            return(response.IsSuccessStatusCode ? OAuthTokenResponse.Success(JsonDocument.Parse(await response.Content.ReadAsStringAsync())) : OAuthTokenResponse.Failed(new Exception("OAuth token failure")));
        }
Example #20
0
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            using var request = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint);
            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            request.Content = new FormUrlEncodedContent(new Dictionary <string, string>
            {
                ["redirect_uri"]          = context.RedirectUri,
                ["client_assertion"]      = Options.ClientSecret,
                ["client_assertion_type"] = AzureDevOpsAuthenticationDefaults.ClientAssertionType,
                ["assertion"]             = context.Code,
                ["grant_type"]            = "urn:ietf:params:oauth:grant-type:jwt-bearer",
            });

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

            if (!response.IsSuccessStatusCode)
            {
                Logger.LogError("An error occurred while retrieving an access token: the remote server " +
                                "returned a {Status} response with the following payload: {Headers} {Body}.",
                                response.StatusCode,
                                response.Headers.ToString(),
                                await response.Content.ReadAsStringAsync());

                return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
            }

            var content = await response.Content.ReadAsStringAsync();

            var payload = JsonDocument.Parse(content);

            return(OAuthTokenResponse.Success(payload));
        }
Example #21
0
    protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
    {
        using var request = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint);
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        request.Headers.Authorization = CreateAuthorizationHeader();

        var parameters = new Dictionary <string, string>
        {
            ["grant_type"]   = "authorization_code",
            ["redirect_uri"] = context.RedirectUri,
            ["code"]         = context.Code
        };

        request.Content = new FormUrlEncodedContent(parameters !);

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

        if (!response.IsSuccessStatusCode)
        {
            await Log.ExchangeCodeErrorAsync(Logger, response, Context.RequestAborted);

            return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
        }

        var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted));

        return(OAuthTokenResponse.Success(payload));
    }
Example #22
0
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            _logger?.LogDebug("ExchangeCodeAsync({code}, {redirectUri})", context.Code, context.RedirectUri);

            var options = Options.BaseOptions();

            options.CallbackUrl = context.RedirectUri;

            var tEx      = new TokenExchanger(options, GetHttpClient());
            var response = await tEx.ExchangeCodeForToken(context.Code, Options.TokenEndpoint, Context.RequestAborted).ConfigureAwait(false);

            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                _logger?.LogDebug("ExchangeCodeAsync() received json: {json}", result);
                var payload       = JsonDocument.Parse(result);
                var tokenResponse = OAuthTokenResponse.Success(payload);

                return(tokenResponse);
            }
            else
            {
                var error = "OAuth token endpoint failure: " + await Display(response).ConfigureAwait(false);

                return(OAuthTokenResponse.Failed(new Exception(error)));
            }
        }
Example #23
0
    protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
    {
        var tokenRequestParameters = new Dictionary <string, string?>
        {
            ["app_id"]       = Options.ClientId,
            ["app_secret"]   = Options.ClientSecret,
            ["code"]         = context.Code,
            ["redirect_uri"] = context.RedirectUri,
        };

        // PKCE https://tools.ietf.org/html/rfc7636#section-4.5, see BuildChallengeUrl
        if (context.Properties.Items.TryGetValue(OAuthConstants.CodeVerifierKey, out var codeVerifier))
        {
            tokenRequestParameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier !);
            context.Properties.Items.Remove(OAuthConstants.CodeVerifierKey);
        }

        var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, tokenRequestParameters);

        using var request  = new HttpRequestMessage(HttpMethod.Get, address);
        using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted);

        if (!response.IsSuccessStatusCode)
        {
            await Log.ExchangeCodeErrorAsync(Logger, response, Context.RequestAborted);

            throw new HttpRequestException("An error occurred while retrieving the user profile.");
        }

        var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync(Context.RequestAborted));

        return(OAuthTokenResponse.Success(payload));
    }
Example #24
0
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            string code        = context.Code;
            string redirectUri = context.RedirectUri;
#endif
            Dictionary <string, string> parameters = new Dictionary <string, string>
            {
                { "grant_type", "authorization_code" },
                { "client_id", Options.ClientId },
                { "client_secret", Options.ClientSecret },
                { "code", code },
                { "redirect_uri", redirectUri }
            };

            string endpoint = QueryHelpers.AddQueryString(Options.TokenEndpoint, parameters);

            HttpResponseMessage response = await Backchannel.GetAsync(endpoint, Context.RequestAborted);

            if (!response.IsSuccessStatusCode)
            {
                return(OAuthTokenResponse.Failed(new Exception("获取QQ Connect Access Token出错。")));
            }
#if NETSTANDARD
            JObject payload = JObject.Parse(企鹅的返回不拘一格传入这里统一转换为JSON(await response.Content.ReadAsStringAsync()));
            return(OAuthTokenResponse.Success(payload));
#else
            string       json     = 企鹅的返回不拘一格传入这里统一转换为JSON(await response.Content.ReadAsStringAsync());
            JsonDocument document = JsonDocument.Parse(json);
            return(OAuthTokenResponse.Success(document));
#endif
        }
Example #25
0
 protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
 {
     using var payload = JsonDocument.Parse(JsonSerializer.Serialize(new Dictionary <string, string>
     {
         { "access_token", context.Code }
     }));
     return(await Task.FromResult(OAuthTokenResponse.Success(payload)));
 }
        /// <summary>
        /// Dingtalk中不需要用Code换取AccessToken,类似直接拿Code当AccessToken用,但是一次性的
        /// </summary>
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            var jsonString = JsonSerializer.Serialize(new { AccessToken = context.Code });

            var payload = JsonDocument.Parse(jsonString);
            var res     = OAuthTokenResponse.Success(payload);

            return(await Task.FromResult(res));
        }
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            Options.ClientId     = context.Properties.Items[nameof(Token.ProviderClientId)];
            Options.ClientSecret = context.Properties.Items[nameof(Token.ProviderClientSecret)];

            var response = await base.ExchangeCodeAsync(context);

            return(response);
        }
Example #28
0
        /// <summary>
        ///  Step2:通过Authorization Code获取Access Token
        ///  http://wiki.connect.qq.com/%E4%BD%BF%E7%94%A8authorization_code%E8%8E%B7%E5%8F%96access_token
        /// </summary>
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary <string, string>()
            {
                ["client_id"]     = Options.ClientId,
                ["client_secret"] = Options.ClientSecret,
                ["code"]          = context.Code,
                ["grant_type"]    = "authorization_code",
                ["redirect_uri"]  = context.RedirectUri,
            });

            var response = await Backchannel.GetAsync(address);

            if (!response.IsSuccessStatusCode)
            {
                Logger.LogError("An error occurred while retrieving an access token: the remote server returned a {Status} response with the following payload: {Headers} {Body}.",
                                /* Status: */ response.StatusCode,
                                /* Headers: */ response.Headers.ToString(),
                                /* Body: */ await response.Content.ReadAsStringAsync());

                return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
            }

            // 成功:  access_token=FE04************************CCE2&expires_in=7776000&refresh_token=88E4************************BE14
            // 失败:  callback( {"error":123456 ,"error_description":"**************"} );

            var responseString = await response.Content.ReadAsStringAsync();

            if (responseString.StartsWith("callback"))
            {
                Logger.LogError("An error occurred while retrieving an access token: the remote server " +
                                "returned a {Status} response with the following payload: {Headers} {Body}.",
                                /* Status: */ response.StatusCode,
                                /* Headers: */ response.Headers.ToString(),
                                /* Body: */ await response.Content.ReadAsStringAsync());

                return(OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token.")));
            }

            JsonDocument payload = JsonDocument.Parse("{}");

            var responseParams = responseString.Split('&');

            var buffer = new ArrayBufferWriter <byte>();
            var write  = new Utf8JsonWriter(buffer);

            foreach (var parm in responseParams)
            {
                var kv = parm.Split('=');

                write.WritePropertyName(kv[0]);
                write.WriteStringValue(kv[1]);
            }

            return(OAuthTokenResponse.Success(payload));
        }
        /// <inheritdoc />
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
        {
            if (Options.GenerateClientSecret)
            {
                var secretGenerationContext = new AppleGenerateClientSecretContext(Context, Scheme, Options);
                await Events.GenerateClientSecret(secretGenerationContext);
            }

            return(await base.ExchangeCodeAsync(context));
        }
Example #30
0
        /// <summary>
        /// This code was copied from the aspnetcore repository . We should keep it in sync with it.
        /// https://github.com/dotnet/aspnetcore/blob/fcd4ed7c46083cc408417763867637f232928f9b/src/Security/Authentication/OAuth/src/OAuthHandler.cs#L193
        /// This can be removed or modified when the https://github.com/dotnet/aspnetcore/issues/33351 is resolved
        /// </summary>
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
        {
            var tokenRequestParameters = new Dictionary <string, string>()
            {
                { "client_id", Options.ClientId },
                { "redirect_uri", context.RedirectUri },
                { "client_secret", Options.ClientSecret },
                { "code", context.Code },
                { "grant_type", "authorization_code" },
            };

            // PKCE https://tools.ietf.org/html/rfc7636#section-4.5, see BuildChallengeUrl
            if (context.Properties.Items.TryGetValue(OAuthConstants.CodeVerifierKey, out var codeVerifier))
            {
                tokenRequestParameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier !);
                context.Properties.Items.Remove(OAuthConstants.CodeVerifierKey);
            }

            var requestContent = new FormUrlEncodedContent(tokenRequestParameters !);

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

            requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            requestMessage.Content = requestContent;
            requestMessage.Version = Backchannel.DefaultRequestVersion;
            var response = await Backchannel.SendAsync(requestMessage, Context.RequestAborted);

            if (response.IsSuccessStatusCode)
            {
                var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());

                // This was added to support better error messages from the GitHub OAuth provider
                if (payload.RootElement.TryGetProperty("error", out var error))
                {
                    var output = new StringBuilder();
                    output.Append(error);

                    if (payload.RootElement.TryGetProperty("error_description", out var description))
                    {
                        output.Append(' ');
                        output.Append(description);
                    }
                    return(OAuthTokenResponse.Failed(new Exception(output.ToString())));
                }

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

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