Подтвердить что ты не робот

Заголовок 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.

Есть ли что-то, что я пропустил?

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

Ответ 4

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