使用HttpClient获取Bearer Token

问题描述 投票:0回答:2

我正在尝试获取不记名令牌:

public override async Task<string> Post(string path, HttpContent content) {


    var encodedConsumerKey = System.Uri.EscapeDataString("1111111111111");
    var encodedConsumerKeySecret = System.Uri.EscapeDataString("2222222222222");
    var encodedPair = Base64Encode(String.Format("{0}:{1}", encodedConsumerKey, encodedConsumerKeySecret));

    HttpRequestMessage request = new HttpRequestMessage{
                                        Method      = HttpMethod.Post,
                                        RequestUri  = new Uri("https://api.twitter.com/oauth2/token"),
                                        Content     = new StringContent("grant_type=client_credentials")
                                    };
    request.Headers.TryAddWithoutValidation("Authorization", String.Format("BASIC {0}", encodedPair));
    request.Headers.TryAddWithoutValidation("Content-Type", "application/x-www-form-urlencoded");


    var result = await HttpClient.SendAsync(request);
    return result.Content.ReadAsStringAsync().Result;
}

private static string Base64Encode(string plainText) {
    var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
    return System.Convert.ToBase64String(plainTextBytes);
}

这给了我以下错误 403“禁止”。任何想法,将不胜感激。

c# oauth dotnet-httpclient
2个回答
25
投票

我能够让它工作。我改变了上面代码中的一些内容。首先是设置

ContentType

requestToken.Content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded") {CharSet = "UTF-8"};

第二个是我错过的一个非常小的细节,降低了

Basic
标头中
Authorization
字符串的大小写。

这是完整的方法,以防万一有人需要它:

public async Task<string> GetAPI(string apiPath)
{

var baseUri = new Uri("https://api.twitter.com/");
var encodedConsumerKey = HttpUtility.UrlEncode("111111111111");
var encodedConsumerKeySecret = HttpUtility.UrlEncode("222222222222");
var encodedPair = Base64Encode(String.Format("{0}:{1}", encodedConsumerKey, encodedConsumerKeySecret));

var requestToken = new HttpRequestMessage
{
    Method = HttpMethod.Post,
    RequestUri = new Uri(baseUri, "oauth2/token"),
    Content = new StringContent("grant_type=client_credentials")
};

requestToken.Content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded") { CharSet = "UTF-8" };
requestToken.Headers.TryAddWithoutValidation("Authorization", String.Format("Basic {0}", encodedPair));

var bearerResult = await HttpClient.SendAsync(requestToken);
var bearerData = await bearerResult.Content.ReadAsStringAsync();
var bearerToken = JObject.Parse(bearerData)["access_token"].ToString();

var requestData = new HttpRequestMessage
{
    Method = HttpMethod.Get,
    RequestUri = new Uri(baseUri, apiPath),
};
requestData.Headers.TryAddWithoutValidation("Authorization", String.Format("Bearer {0}", bearerToken));

var results = await HttpClient.SendAsync(requestData);
return await results.Content.ReadAsStringAsync();

}

0
投票

简化的解决方案

我有类似的需求,最终得到了一个更优雅的解决方案,我想分享。这是一个简化版本,仅从 OAuth2 服务器获取响应并返回它,但它可以轻松地适应与

HttpClientFactory
、依赖项注入或您需要的任何其他方式一起使用。

private async Task<Authorization?> Authorize()
{
    var httpClient = new HttpClient();

    var clientId = HttpUtility.UrlEncode("");     // Put your client ID here
    var clientSecret = HttpUtility.UrlEncode(""); // Put your client secret here
    var authorizationToken = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{clientId}:{clientSecret}"));

    httpClient.BaseAddress = new(""); // Put your OAuth2 server base address here (with trailing slash)
    httpClient.DefaultRequestHeaders.Authorization = new("Basic", authorizationToken);
    httpClient.DefaultRequestHeaders.Accept.Add(new("application/json")); // This might need to be adjusted, depending on your response format

    FormUrlEncodedContent authorizationRequestContent = new(new Dictionary<string, string>
    {
        { "grant_type", "client_credentials" }  // Add dictionary entries according to your needs
    });

    var responseMessage = await httpClient.PostAsync("", authorizationRequestContent); // Put here the relative URL to the endpoint (without slash at the beginning)
    var authorization = await responseMessage.Content.ReadFromJsonAsync<Authorization>(); // Define your response as a class for deserialization

    return authorization;
}
© www.soinside.com 2019 - 2024. All rights reserved.