web-dev-qa-db-fra.com

L'en-tête d'authentification HttpClient n'est pas envoyé

J'essaie d'utiliser un HttpClient pour un service tiers qui nécessite une authentification HTTP de base. J'utilise le AuthenticationHeaderValue. Voici ce que j'ai trouvé jusqu'à présent:

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;

Il semble que l'action POST fonctionne bien, mais je ne récupère pas les données que j'attends. Grâce à des essais et des erreurs, et finalement à l'aide de Fiddler pour flairer le trafic brut, j'ai découvert l'autorisation l'en-tête n'est pas envoyé.

J'ai vu this , mais je pense avoir le schéma d'authentification spécifié dans le cadre du constructeur AuthenticationHeaderValue.

Y a-t-il quelque chose que j'ai manqué?

21
Ross

Votre code semble qu'il devrait fonctionner - je me souviens avoir rencontré un problème similaire en définissant les en-têtes d'autorisation et résolu en faisant un Headers.Add () au lieu de le définir:

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

PDATE: Cela ressemble à lorsque vous faites une requête. Contenu, tous les en-têtes ne sont pas reflétés dans l'objet de contenu. Vous pouvez le voir en inspectant request.Headers vs request.Content.Headers. Une chose que vous voudrez peut-être essayer est d'utiliser SendAsync au lieu de PostAsync. Par exemple:

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;
30
Hai Nguyen

Cela fonctionnerait également et vous n'auriez pas à gérer les conversions de chaînes en base64:

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

Essayez de définir l'en-tête sur le client:

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

Cela fonctionne pour moi.

17
David Peden

En fait, votre problème est avec PostAsync- vous devez utiliser SendAsync. Dans votre code - client.PostAsync(Uri, request.Content); envoie uniquement le contenu, les en-têtes de message de demande ne sont pas inclus. La bonne façon est:

HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, url)
{
    Content = content
};
message.Headers.Authorization = new AuthenticationHeaderValue("Basic", credentials);
httpClient.SendAsync(message);
4
Indomitable