/// <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))); } }
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)); }
/// <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出错。"))); } }
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)); }
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))); } }
/// <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)); }
/// <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) });
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)); }
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)); }
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)); }
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)); }
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"))); }
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)); }
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)); }
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))); } }
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)); }
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 }
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); }
/// <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)); }
/// <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))); } }