たまたま、クライアントが基本認証を使用することを要求するAPIを使用してREST Webサービスを実行します。サービスとのインターフェース方法を示す、さまざまな言語のきちんとしたサンプルのセットを作成しました。 。現在、サービスのIISログを確認しており、次のパターンが頻繁に発生することを確認しています。
これは、最初のリクエストがAuthorizationヘッダーなしで送信され、2番目のリクエストが正しいヘッダー付きで送信されて成功したように見えます。ほとんどの場合、ログレコードには、.NETサンプルに植え付けたのと同じ文字列である「user-agent」が含まれています。
したがって、問題は.NETプログラムのみにあると思います。サンプルコードでは問題が再現されていないため、ユーザーが何らかの方法でコードを変更したか、独自に作成したと思います。
ユーザーに連絡してみましたが、どうやら彼らは研究に時間を費やしたくないようです。したがって、.NETプログラムのこの動作につながる可能性が最も高いシナリオを見つけるのは良いことです。
なぜ彼らはこれをするのでしょうか?なぜ彼らは最初の試みでヘッダーを付けないのでしょうか?
これは、次の方法で公開されるHttpClient
クラスとHttpWebRequest
クラスのデフォルトの動作です。
注:以下のテキストは、質問で説明されている問題を引き起こす次善の動作を説明しています。ほとんどの場合、このようなコードを書くべきではありません。代わりに、修正されたコードまで下にスクロールしてください
どちらの場合も、NetworkCredenatial
オブジェクトをインスタンス化し、そこにユーザー名とパスワードを設定します
var credentials = new NetworkCredential( username, password );
HttpWebRequest
--set .Credentials
プロパティを使用する場合:
webRequest.Credentials = credentials;
HttpClient
を使用する場合-資格情報オブジェクトをHttpClientHandler
に渡します( ここ から変更されたコード):
var client = new HttpClient(new HttpClientHandler() { Credentials = credentials })
次に、Fiddlerを実行して、リクエストを開始します。次のように表示されます。
この動作は説明されています ここ -クライアントはサービスがBasicを必要とすることを事前に知らず、認証プロトコルをネゴシエートしようとします(そしてサービスがDigest送信が必要ですOpenのBasicヘッダーは役に立たず、クライアントを危険にさらす可能性があります)。
注:ここで、次善の動作の説明が終了し、より良いアプローチが説明されます。ほとんどの場合、上からのコードではなく、下からのコードを使用する必要があります。
サービスにBasicが必要であることがわかっている場合は、次の方法で余分なリクエストを削除できます。
.Credentials
を設定せず、代わりに here のコードを使用してヘッダーを手動で追加します。ユーザー名とパスワードをエンコードします。
var encoded = Convert.ToBase64String( Encoding.ASCII.GetBytes(
String.Format( "{0}:{1}", username, password ) ) );
HttpWebRequest
を使用する場合は、ヘッダーに追加します。
request.Headers.Add( "Authorization", "Basic " + encoded );
HttpClient
を使用する場合は、デフォルトのヘッダーに追加します。
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue( "Basic", encoded );
これを行うと、リクエストは毎回適切な認証ヘッダーとともに送信されます。 は.Credentials
を設定しないでください、そうでない場合はユーザー名またはパスワードが間違っていることに注意してください同じリクエストが、間違った資格情報を使用して2回送信され、もちろん両方の時間でHTTP401が生成されます。