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

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

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


当前回答

在net .core中,您可以使用Identity Server 4

var client = new HttpClient();
client.SetBasicAuthentication(userName, password);

or

var client = new HttpClient();
client.SetBearerToken(token);

参见https://github.com/IdentityModel/IdentityModel/blob/main/src/Client/Extensions/AuthorizationHeaderExtensions.cs

其他回答

方法是这样的,

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

对于现在(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,所有的请求都会有承载者。

对于性能和端口耗尽问题,重用HttpClient实例是一个很好的实践,而且因为没有一个答案给出了这个解决方案(甚至会把你引向糟糕的实践:),所以我在这里放了一个链接,指向我对类似问题的回答:

https://stackoverflow.com/a/40707446/717372

一些关于如何正确使用HttpClient的源代码:

https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/ https://blogs.msdn.microsoft.com/alazarev/2017/12/29/disposable-finalizers-and-httpclient/

使用c# HttpClient设置基本身份验证。下面的代码为我工作。

   using (var client = new HttpClient())
        {
            var webUrl ="http://localhost/saleapi/api/";
            var uri = "api/sales";
            client.BaseAddress = new Uri(webUrl);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.ConnectionClose = true;

            //Set Basic Auth
            var user = "username";
            var password = "password";
            var base64String =Convert.ToBase64String( Encoding.ASCII.GetBytes($"{user}:{password}"));
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",base64String);

            var result = await client.PostAsJsonAsync(uri, model);
            return result;
        }