Заголовок аутентификации HttpClient не отправляется

Я пытаюсь использовать 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 конструктор.

Я что-то пропустил?

5 ответов

Решение

Ваш код выглядит так, как будто он должен работать - я помню, что сталкивался с подобной проблемой установки заголовков авторизации и решил ее, выполнив Headers.Add() вместо установки:

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

ОБНОВЛЕНИЕ: Похоже, когда вы делаете запрос. Содержимое, не все заголовки отражаются в объекте содержимого. Вы можете убедиться в этом, проверив 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;

Это также будет работать, и вам не придется иметь дело с преобразованиями строк base64:

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

Попробуйте установить заголовок на клиенте:

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

Это работает для меня.

На самом деле ваша проблема с 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);

Кроме того, учтите , что Redirect-Handler очистит заголовок авторизации, если ваш запрос будет перенаправлен. Поэтому, если вы вызываете конечную точку HTTP, и она перенаправляется на HTTPS, вы потеряете свой заголовок авторизации.

      request.Headers.Authorization = null;

Фреймворк: .NET v6.0

Другие вопросы по тегам