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

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

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


当前回答

use UTF8选项

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

其他回答

我在寻找一个好的方法来处理这个问题,我也在考虑同样的问题。希望这个答案能帮助到每个和我一样有同样问题的人。

using (var client = new HttpClient())
{
    var url = "https://www.theidentityhub.com/{tenant}/api/identity/v1";
    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
    var response = await client.GetStringAsync(url);
    // Parse JSON response.
    ....
}

参考来自https://www.theidentityhub.com/hub/Documentation/CallTheIdentityHubApi

6年过去了,但为了帮助别人,我加了这个。

https://www.codeproject.com/Tips/996401/Authenticate-WebAPIs-with-Basic-and-Windows-Authen

var authenticationBytes = Encoding.ASCII.GetBytes("<username>:<password>");
using (HttpClient confClient = new HttpClient())
{
  confClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", 
         Convert.ToBase64String(authenticationBytes));
  confClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(Constants.MediaType));  
  HttpResponseMessage message = confClient.GetAsync("<service URI>").Result;
  if (message.IsSuccessStatusCode)
  {
    var inter = message.Content.ReadAsStringAsync();
    List<string> result = JsonConvert.DeserializeObject<List<string>>(inter.Result);
  }
}

使用基本授权和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();
}

我偶然发现了这条旧线索。我遇到的问题是我知道使用静态HttpClient,但是我的令牌需要每59分钟刷新一次。

所以我可以使用HttpClientFactory,但是因为我的一个项目仍然在. net 4.8中,我创建了一个从HttpClient继承的类,所以我在所有项目中都有类似的代码。需要一个秘密才能获得令牌(我使用identityserver4)。

然后我将它设置为DI中的单例(我在这里使用Ninject):

Bind<MyHttpClient>().ToMethod(c =>
{
    var accessKey = ConfigurationManager.AppSettings["AccessKey"];

    var client = new MyHttpClient(accessKey)
    {
        BaseAddress = new Uri(MyUrls.MyApiBaseUrl)
    };

    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

    return client;
}).InSingletonScope();

然后是类本身——以它用来访问的API命名:

public class MyHttpClient : BaseHttpClient
{
     private static readonly HttpClient _authHttpClient = new HttpClient();
     private string _secret;

     public MyHttpClient(string secret)
     {
         _secret = secret;
     }

    /// <summary>
    /// Add the token to each and every request, cached for 1 minute less than the token's lifetime
    /// </summary>
    /// <param name="request"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    public override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();

        var cacheSeconds = 3600 - 60; // Default of 59 minutes

        var token = CacheHelper<string>.Get("MyToken", cacheSeconds * 60, () =>
        {
            var authorityUrl = MyUrls.AuthServerUrl;

            // discover endpoints from metadata
            DiscoveryDocumentResponse disco;
            disco = _authHttpClient.GetDiscoveryDocumentAsync(authorityUrl).Result;
            if (disco.IsError)
            {
                throw new Exception("Error getting discovery document: " + disco.Error);
            }

            // request token
            var tokenResponse = _authHttpClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
            {
                Address = disco.TokenEndpoint,

                ClientId = "myapp",
                ClientSecret = _secret,
                Scope = "myapi"
            }).Result;

            if (tokenResponse.IsError)
            {
                throw new Exception("Error getting token: " + tokenResponse.Error);
            }

            if (tokenResponse.ExpiresIn < cacheSeconds + 60)
            {
                throw new Exception($"Token expires in {tokenResponse.ExpiresIn}s, which is less than {cacheSeconds + 60}");
            }

            if (tokenResponse.ExpiresIn > cacheSeconds + 60)
            {
                Log.Warn().Message($"Token expiry in {tokenResponse.ExpiresIn}s, which is greater than {cacheSeconds}").Write();
            }

            return tokenResponse.AccessToken;
        });

        // THIS IS THE BIT - Assign this inside a SendAsync override and you are done!
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
        return base.SendAsync(request, cancellationToken);
    }

}

最后为了完整起见,我的CacheHelper类看起来是这样的:

public static class CacheHelper<T>
{
    private static readonly object _locker = new object();

    public static T Get(string cacheName, int cacheTimeoutSeconds, Func<T> func)
    {
        var obj = MemoryCache.Default.Get(cacheName, null);
        if (obj != null) return (T)obj;

        lock (_locker)
        {
            obj = MemoryCache.Default.Get(cacheName, null);
            if (obj == null)
            {
                obj = func();
                var cip = new CacheItemPolicy
                {
                    AbsoluteExpiration = new DateTimeOffset(DateTime.UtcNow.AddSeconds(cacheTimeoutSeconds))
                };
                MemoryCache.Default.Set(cacheName, obj, cip);
            }
        }

        return (T)obj;
    }
}

使用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;
        }