C# HttpClient 身份验证标头未发送

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10077237/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 12:22:18  来源:igfitidea点击:

HttpClient authentication header not getting sent

c#.net-4.5wcf-web-apidotnet-httpclient

提问by Ross

I'm trying to use an HttpClientfor a third-party service that requires basic HTTP authentication. I am using the AuthenticationHeaderValue. Here is what I've come up with so far:

我正在尝试将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;

It looks like the POST action works fine, but I don't get back the data I expect. Through some trial and error, and ultimately using Fiddler to sniff the raw traffic, I discovered the authorization header isn't being sent.

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

I've seen this, but I think I've got the authentication scheme specified as a part of the AuthenticationHeaderValueconstructor.

我已经看到了这个,但我想我已经将身份验证方案指定为AuthenticationHeaderValue构造函数的一部分。

Is there something I've missed?

有什么我错过了吗?

采纳答案by Hai Nguyen

Your code looks like it should work - I remember running into a similar problem setting the Authorization headers and solved by doing a Headers.Add() instead of setting it:

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

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

UPDATE:It looks like when you do a request.Content, not all headers are being reflected in the content object. You can see this by inspecting request.Headers vs request.Content.Headers. One thing you might want to try is to use SendAsync instead of PostAsync. For example:

更新:看起来当您执行 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;

回答by David Peden

Try setting the header on the client:

尝试在客户端设置标题:

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

This works for me.

这对我有用。

回答by Nitin Agarwal

This would also work and you wouldn't have to deal with the base64 string conversions:

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

var handler = new HttpClientHandler();
handler.Credentials = new System.Net.NetworkCredential("username", "password");
var client = new HttpClient(handler);
...

回答by Indomitable

Actually your problem is with PostAsync- you should use SendAsync. In your code - client.PostAsync(Uri, request.Content);sends only the content the request message headers are not included. The proper way is:

实际上你的问题是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);