残念ながら、(WCF 参照ソース コードと HTTP セッション スニッフィング用の Fiddler ツールの助けを借りて) これが WCF スタックのバグであると判断しました。
Fiddler を使用して、WCF サービスが基本認証を使用する他の Web サイトとは異なる動作をしていることに気付きました。
明確にするために、これは何が起こるべきかです:
- ブラウザ
GET
は、パスワードが必要であることさえ知らずにリクエストを送信します。
401 Unauthorized
Web サーバーは、ステータスとともに要求を拒否し、WWW-Authenticate
受け入れ可能な認証方法に関する情報を含むヘッダーを含めます。
- ブラウザーはユーザーに資格情報の入力を求めます。
- ブラウザー
GET
は要求を再送信し、資格情報を含む適切なAuthentication
ヘッダーを含めます。
200 OK
資格情報が正しければ、Web サーバーはWeb ページで応答します。資格情報が間違っていた場合、Web サーバーは応答し、手順 2 で行ったもの401 Unauthorized
と同じWWW-Authenticate
ヘッダーを含めます。
私のWCFサービスで実際に起こっていたのはこれでした:
- ブラウザ
GET
は、パスワードが必要であることさえ知らずにリクエストを送信します。
- WCF は、要求にヘッダーが含まれていないことを認識し、ステータス
Authentication
と共に要求をやみくもに拒否し、ヘッダーを含めます。これまでのところすべて正常です。401 Unauthorized
WWW-Authenticate
- ブラウザはユーザーに資格証明を要求します。まだ正常です。
- ブラウザーは、適切なヘッダー
GET
を含む要求を再送信します。Authentication
- 資格情報が正しかった場合、Web サーバーは で応答し
200 OK
ます。すべて良好。ただし、資格情報が間違っていた場合、WCF は応答し403 Forbidden
、WWW-Authenticate
.
ブラウザが403 Forbidden
ステータスを取得しても、これが認証試行の失敗であるとは認識されません。このステータス コードは、アクセスしようとした URL が立ち入り禁止であることをブラウザに通知することを目的としています。認証とはまったく関係ありません。これには、ユーザーがユーザー名/パスワードを間違って入力した場合 (そしてサーバーが 403 で拒否した場合) に、Web ブラウザーがユーザーに資格情報の再入力を求めるプロンプトを表示しないという恐ろしい副作用があります。実際、Web ブラウザは認証が成功したと認識し、セッションの残りの部分でそれらの資格情報を保存します!
これを念頭に置いて、私は明確化を求めました:
RFC 2617 ( http://www.faqs.org/rfcs/rfc2617.html#ixzz0eboUfnrl403 Forbidden
) は、ステータス コードの使用についてどこにも言及していません。実際、この問題について実際に言わなければならないことは次のとおりです。
オリジンサーバーがリクエストで送信されたクレデンシャルを受け入れたくない場合、401 (Unauthorized) レスポンスを返す必要があります。応答には、要求されたリソースに適用可能な少なくとも 1 つの (場合によっては新しい) チャレンジを含む WWW-Authenticate ヘッダー フィールドを含める必要があります。
WCF はこれらのどちらも行いません。401 Unauthorized
ステータス コードも正しく送信されません。WWW-Authenticate
また、ヘッダーも含まれません。
次に、WCF ソース コード内で決定的な証拠を見つけます。
HttpRequestContext
クラスに というメソッドがあり、次の内容が含まれていることがわかりProcessAuthentication
ました (抜粋):
if (!authenticationSucceeded)
{
SendResponseAndClose(HttpStatusCode.Forbidden);
}
私は多くの点でマイクロソフトを擁護していますが、これは弁護の余地がありません。
幸いなことに、「許容できる」レベルまで機能しています。ユーザーが誤ってユーザー名/パスワードを誤って入力した場合、もう一度試行する唯一の方法は、Web ブラウザーを完全に閉じて再起動し、再試行することです。すべては、WCF が失敗した認証の試行に、仕様に従ってヘッダーとヘッダーで応答しないためです。401 Unauthorized
WWW-Authenticate