25

我正在尝试将HttpClient用于需要基本 HTTP 身份验证的第三方服务。我正在使用AuthenticationHeaderValue. 到目前为止,这是我想出的:

HttpRequestMessage<RequestType> request = 
    new HttpRequestMessage<RequestType>(
        new RequestType("third-party-vendor-action"),
        MediaTypeHeaderValue.Parse("application/xml"));
request.Headers.Authorization = new AuthenticationHeaderValue(
    "Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(
        string.Format("{0}:{1}", "username", "password"))));

var task = client.PostAsync(Uri, request.Content);
ResponseType response = task.ContinueWith(
    t =>
    {
        return t.Result.Content.ReadAsAsync<ResponseType>();
    }).Unwrap().Result;

看起来 POST 操作工作正常,但我没有取回我期望的数据。通过一些试验和错误,最终使用 Fiddler 嗅探原始流量,我发现授权标头没有被发送。

我见过这个,但我认为我已经将身份验证方案指定为AuthenticationHeaderValue构造函数的一部分。

有什么我错过的吗?

4

4 回答 4

37

您的代码看起来应该可以工作 - 我记得在设置授权标头时遇到了类似的问题,并通过执行 Headers.Add() 而不是设置它来解决:

request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "username", "password"))));

更新: 看起来当您执行 request.Content 时,并非所有标头都反映在内容对象中。您可以通过检查 request.Headers 与 request.Content.Headers 来看到这一点。您可能想尝试的一件事是使用 SendAsync 而不是 PostAsync。例如:

HttpRequestMessage<RequestType> request = 
     new HttpRequestMessage<RequestType>(
         new RequestType("third-party-vendor-action"),
         MediaTypeHeaderValue.Parse("application/xml"));

request.Headers.Authorization = 
    new AuthenticationHeaderValue(
        "Basic", 
        Convert.ToBase64String(
            System.Text.ASCIIEncoding.ASCII.GetBytes(
                string.Format("{0}:{1}", "username", "password"))));

 request.Method = HttpMethod.Post;
 request.RequestUri = Uri;
 var task = client.SendAsync(request);

 ResponseType response = task.ContinueWith(
     t => 
         { return t.Result.Content.ReadAsAsync<ResponseType>(); })
         .Unwrap().Result;
于 2012-04-16T20:54:51.933 回答
19

这也可以工作,您不必处理 base64 字符串转换:

var handler = new HttpClientHandler();
handler.Credentials = new System.Net.NetworkCredential("username", "password");
var client = new HttpClient(handler);
...
于 2014-03-14T13:36:05.573 回答
18

尝试在客户端设置标题:

DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", userName, password))));

这对我有用。

于 2012-05-17T01:58:58.510 回答
6

实际上你的问题是PostAsync- 你应该使用SendAsync. 在您的代码中 -client.PostAsync(Uri, request.Content);仅发送不包含请求消息标头的内容。正确的方法是:

HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, url)
{
    Content = content
};
message.Headers.Authorization = new AuthenticationHeaderValue("Basic", credentials);
httpClient.SendAsync(message);
于 2015-03-06T12:30:05.743 回答