protected virtual async Task <OAuthTokenResponse> ExchangeCodeAsync(string code, string redirectUri, AuthenticationProperties properties) { var tokenRequestParameters = new Dictionary <string, string>() { { "client_id", Options.ClientId }, { "redirect_uri", redirectUri }, { "client_secret", Options.ClientSecret }, { "code", code }, { "grant_type", "authorization_code" }, }; var exchangeCodeContext = new OAuthExchangeCodeContext(properties, Context, Scheme, Options, tokenRequestParameters); await Events.OnExchangeCode(exchangeCodeContext); var requestContent = new FormUrlEncodedContent(tokenRequestParameters); var requestMessage = new HttpRequestMessage(HttpMethod.Post, Options.TokenEndpoint); requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); requestMessage.Content = requestContent; var response = await Backchannel.SendAsync(requestMessage, 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 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); 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))); } }