2012-04-09 10 views
18

Sto tentando di utilizzare uno HttpClient per un servizio di terze parti che richiede l'autenticazione HTTP di base. Sto usando il AuthenticationHeaderValue. Ecco quello che mi è venuta in mente finora:L'intestazione di autenticazione HttpClient non viene inviata

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; 

Sembra che l'azione POST funziona bene, ma non tornare i dati mi aspetto. Attraverso alcuni tentativi ed errori, e in definitiva usando Fiddler per fiutare il traffico non elaborato, ho scoperto che l'intestazione dell'autorizzazione non è stata inviata.

Ho visto this, ma penso di aver ottenuto lo schema di autenticazione specificato come parte del costruttore AuthenticationHeaderValue.

C'è qualcosa che ho perso?

risposta

25

Il codice sembra che dovrebbe funzionare - Mi ricordo di incorrere in un problema simile impostazione le intestazioni di autorizzazione e risolto facendo un Headers.Add() invece di impostare esso:

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

UPDATE: Sembra che quando fai una richiesta. Contenuto, non tutte le intestazioni si riflettono nell'oggetto di contenuto. Puoi vedere questo ispezionando request.Headers vs request.Content.Headers. Una cosa che potresti voler provare è usare SendAsync invece di PostAsync. Per esempio:

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; 
+0

ho provato e qualcosa di simile con 'request.Headers.Authorization' con gli stessi risultati. Mi ha lasciato un pò di grattacapo perché non sono del tutto sicuro di cosa provare dopo. So che MVC4 beta e l'anteprima 4.5 sono direttamente incompatibili per alcune cose - mi chiedo se questo abbia qualcosa a che fare con questo? – Ross

+0

L'aggiornamento sembra inviare almeno l'intestazione di autorizzazione. Non sono ancora in grado di recuperare i dati dal servizio di terze parti ancora (probabilmente qualcos'altro che non va nel corpo della richiesta che ho perso), ma almeno le intestazioni corrette stanno andando oltre il filo. È un inizio Grazie! – Ross

+0

ASCII o UTF-8? Vedi http://stackoverflow.com/questions/11743160/how-do-i-encode-and-decode-a-base64-string. – Philippe

17

provare a impostare l'intestazione sul client:

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

Questo funziona per me.

+1

Probabilmente funzionerebbe, ma imposterà le intestazioni di autorizzazione per tutte le richieste, vero? Non è desiderabile. – Ross

+2

Per tutte le richieste effettuate con quell'istanza di un client, sì. Stai utilizzando lo stesso client per accedere a endpoint con diversi schemi di autenticazione? Ad esempio, stai impostando il BaseAddress sull'istanza client o no? –

15

Questo sarebbe anche lavorare e non si sarebbe avere a che fare con le conversioni di stringhe base64:

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

soluzione molto più pulita rispetto alla codifica UID: combinazione PWD. –

2

In realtà il problema è con PostAsync - si dovrebbe usare SendAsync. Nel tuo codice - client.PostAsync(Uri, request.Content); invia solo il contenuto che le intestazioni dei messaggi di richiesta non sono incluse. Il modo corretto è:

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

Mille volte grazie. Ho passato ore a cercare di collegare le intestazioni a HttpClient e utilizzare GetAsync e PostAsync ecc. In generale, trovo che WebAPI sia un problema (dammi ServiceStack !!) –

Problemi correlati