2012-04-09 10 views
18

基本的なHTTP認証が必要なサードパーティのサービスにHttpClientを使用しようとしています。私はAuthenticationHeaderValueを使用しています。これまで私がこれまで出てきたことは次のとおりです。HttpClient認証ヘッダーが送信されない

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を使って生のトラフィックを盗聴することで、認証ヘッダーが送信されていないことがわかりました。

私はthisを見ましたが、AuthenticationHeaderValueコンストラクタの一部として指定された認証方式があると思います。

私が見逃したことはありますか?

答えて

25

それが動作するはずのようにあなたのコードが見える - 私は認証ヘッダを設定し、同様の問題に実行して覚えていて、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を調べることで確認できます。試したいことの1つは、PostAsyncの代わりにSendAsyncを使用することです。たとえば:

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

私はそれと同じ結果にrequest.Headers.Authorization' 'と同様のものを試してみました。それは私が次に何を試すべきか完全にはわからないので、頭を傷つける人のビットで私を残しました。私は、MVC4のベータ版と4.5のプレビューは、いくつかのことで直接互換性がないことを知っています。 – Ross

+0

更新プログラムは、少なくとも承認ヘッダーを送信しているようです。私はまだサードパーティのサービスからデータを取得することができません(おそらく私が逃した要求の本体で間違っているかもしれませんが)少なくとも正しいヘッダーが配線されています。それはスタートです。ありがとうございました! – Ross

+0

ASCIIまたはUTF-8? http://stackoverflow.com/questions/11743160/how-do-i-encode-and-decode-a-base64-stringを参照してください。 – Philippe

17

は、クライアント上でヘッダーを設定してみてください:

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

これは私のために動作します。

+1

これはおそらく動作しますが、すべての要求に対して承認ヘッダーを設定しますが、そうではありませんか?それは望ましくない。 – Ross

+2

クライアントのそのインスタンスで行われたすべての要求に対して、はい。さまざまな認証方式を持つエンドポイントに同じクライアントを使用してアクセスしていますか?つまり、クライアントインスタンスでBaseAddressを設定しているかどうかを確認しますか? –

15

また、これはうまくいくと、あなたはbase64で文字列変換に対処する必要がないだろう。

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

UID:PWDの組み合わせをコード化するよりもはるかにクリーンなソリューションです。 –

2

実際にあなたの問題は、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); 
+0

数千回ありがとうございます。私はHttpClientにヘッダーを添付し、GetAsyncとPostAsyncなどを使用して、WebAPIに痛みを感じている時間を費やしました(ServiceStackをくれ!!) –

関連する問題