Заголовок аутентификации 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