我有一个HttpClient,我正在使用一个REST API。但是,我在设置授权标头时遇到了麻烦。我需要将标头设置为我从执行OAuth请求中接收到的令牌。 我看到了一些。net的代码,建议如下:

httpClient.DefaultRequestHeaders.Authorization = new Credential(OAuth.token);

然而,凭据类在WinRT中不存在。有人知道如何设置授权头吗?


当前回答

static async Task<AccessToken> GetToken()
{
        string clientId = "XXX";
        string clientSecret = "YYY";
        string credentials = String.Format("{0}:{1}", clientId, clientSecret);

        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials)));
            List<KeyValuePair<string, string>> requestData = new List<KeyValuePair<string, string>>();
            requestData.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
            FormUrlEncodedContent requestBody = new FormUrlEncodedContent(requestData);
            var request = await client.PostAsync("https://accounts.spotify.com/api/token", requestBody);
            var response = await request.Content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<AccessToken>(response);
        }
    }

其他回答

方法是这样的,

httpClient.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", "Your Oauth token");

对于现在(2021年)找到这个旧线程的人,请看看这个关于HttpClientFactory的文档,它是可注入的,也会在每个请求上重新运行,避免过期的令牌,这将使它对承载令牌,生成的客户端,池等有用。

TL;DR:使用HttpClientFactory和一个DelegatingHandler,它将作为与您配置的客户端的所有外发请求的中间件。

这就是我如何为Azure身份添加我的承载者(由Azure管理),但你当然可以获得你想要的令牌;

using Microsoft.Azure.Services.AppAuthentication;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

public class BearerTokenHandler : DelegatingHandler
    {
        public BearerTokenHandler(AzureServiceTokenProvider tokenProvider, string resource)
        {
            TokenProvider = tokenProvider;
            Resource = resource;
        }

        public AzureServiceTokenProvider TokenProvider { get; }
        public string Resource { get; }

        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (!request.Headers.Contains("Authorization"))
            {
                // Fetch your token here
                string token = await TokenProvider.GetAccessTokenAsync(Resource);
                request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
            }

            return await base.SendAsync(request, cancellationToken);
        }
    }

我在Startup中这样配置我的类型化客户端(用NSwag生成);

   var accessTokenProvider = new AzureServiceTokenProvider("<your-connection-string-for-access-token-provider>");

  builder.Services.AddHttpClient<IOrdersClient, OrdersClient>().ConfigureHttpClient(async conf =>
            {
                conf.BaseAddress = new Uri("<your-api-base-url>");
            }).AddHttpMessageHandler(() => new BearerTokenHandler(accessTokenProvider, "https://your-azure-tenant.onmicrosoft.com/api"));

然后你可以在任何你喜欢的地方注入你的IOrdersClient,所有的请求都会有承载者。

request.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue(
        "Basic", Convert.ToBase64String(
            System.Text.ASCIIEncoding.ASCII.GetBytes(
               $"{yourusername}:{yourpwd}")));

使用基本授权和Json参数。

using (HttpClient client = new HttpClient())
{
    var request_json = "your json string";

    var content = new StringContent(request_json, Encoding.UTF8, "application/json");

    var authenticationBytes = Encoding.ASCII.GetBytes("YourUsername:YourPassword");

    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
            Convert.ToBase64String(authenticationBytes));
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var result = await client.PostAsync("YourURL", content);

    var result_string = await result.Content.ReadAsStringAsync();
}

BaseWebApi.cs

public abstract class BaseWebApi
{
    //Inject HttpClient from Ninject
    private readonly HttpClient _httpClient;
    public BaseWebApi(HttpClient httpclient)
    {
        _httpClient = httpClient;
    }

    public async Task<TOut> PostAsync<TOut>(string method, object param, Dictionary<string, string> headers, HttpMethod httpMethod)
    {
        //Set url

        HttpResponseMessage response;
        using (var request = new HttpRequestMessage(httpMethod, url))
        {
            AddBody(param, request);
            AddHeaders(request, headers);
            response = await _httpClient.SendAsync(request, cancellationToken);
        }

        if(response.IsSuccessStatusCode)
        {
             return await response.Content.ReadAsAsync<TOut>();
        }
        //Exception handling
    }

    private void AddHeaders(HttpRequestMessage request, Dictionary<string, string> headers)
    {
        request.Headers.Accept.Clear();
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        if (headers == null) return;

        foreach (var header in headers)
        {
            request.Headers.Add(header.Key, header.Value);
        }
    }

    private static void AddBody(object param, HttpRequestMessage request)
    {
        if (param != null)
        {
            var content = JsonConvert.SerializeObject(param);
            request.Content = new StringContent(content);
            request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
        }
    }

SubWebApi.cs

public sealed class SubWebApi : BaseWebApi
{
    public SubWebApi(HttpClient httpClient) : base(httpClient) {}

    public async Task<StuffResponse> GetStuffAsync(int cvr)
    {
        var method = "get/stuff";
        var request = new StuffRequest 
        {
            query = "GiveMeStuff"
        }
        return await PostAsync<StuffResponse>(method, request, GetHeaders(), HttpMethod.Post);
    }
    private Dictionary<string, string> GetHeaders()
    {
        var headers = new Dictionary<string, string>();
        var basicAuth = GetBasicAuth();
        headers.Add("Authorization", basicAuth);
        return headers;
    }

    private string GetBasicAuth()
    {
        var byteArray = Encoding.ASCII.GetBytes($"{SystemSettings.Username}:{SystemSettings.Password}");
        var authString = Convert.ToBase64String(byteArray);
        return $"Basic {authString}";
    }
}