ActiveDirectoryを使用して認証を行うASP.NET Webサイトがあります。
現在、認証されたユーザーがページを開くと、自動的に認証されます。私は問題に直面しました-認証されていないユーザー(、たとえば、network.automatic-ntlm-auth.trusted-uris
プロパティが定義されていないMozilla Firefoxユーザー)がページ、IIS 401応答を送信し、ログイン\パスワードの入力を求めます。
私が欲しいのはログイン\パスワードの入力を求めない-カスタムエラーページを表示するだけです。非常に単純に聞こえます。認証されたユーザーは要求されたページを取得し、認証されていないユーザーはカスタムエラーページにリダイレクトされます。 FormsAuthenticationの場合は問題なく動作します。
しかし、私はこれまでに多くの方法を試してきました。 Web.configリダイレクトが機能していません。 Response
をクリアしてリダイレクトを設定しても、このカスタムページ(*例:/Error/AccessDenied
)にも認証が必要なため、ループが発生します。コントローラをAllowAnonymous
としてマークしても何も起こりません。
ただし、IIS Managerで匿名認証を有効にすると、実際に認証されたドメインユーザーは、Webサイトを開いたときに認証されません。
どうすればこの問題を解決できますか?
コメントでどのように機能するかを説明してくれた@Abhitalksに感謝します。理由はわかりませんが、IEとGoogle Chromeが最初のリクエストで認証ヘッダーを送信しているので、許可されていないユーザーのみが送信されていると確信していました401応答を取得します。401応答をまったく回避できないことを理解した後、この動作が望ましいものに最も近いため、この単純なアプローチを使用することにしました。
Global.asax
に次のメソッドを追加しました。
protected void Application_EndRequest(object sender, EventArgs e)
{
if (Response.StatusCode == 401)
{
Response.ClearContent();
Response.WriteFile("~/Static/NotAuthorized.html");
Response.ContentType = "text/html";
}
}
これで、ユーザーがページを開くと、サーバーはカスタムエラーページを返しますが、401 Unauthorized
ヘッダーが付いています。
Chrome、IEまたは適切に構成されたFirefox。ユーザーがURLを要求すると、サーバーは401ヘッダー付きのエラーページを返します-ブラウザは自動的に認証チャレンジを完了し、にリダイレクトします同じURLの場合、サーバーは正しいページと200を返します。ユーザーにはこのエラーページは表示されません。
未構成のFirefox。ユーザーがURLを要求すると、サーバーは401ヘッダー付きのエラーページを返します。ブラウザーは認証チャレンジを完了できず、ユーザーに資格情報の入力を求めます。
ユーザーが正しいログインを入力します。ユーザーは再び同じURLをリクエストし、ページを取得して200 OKを取得します。
ユーザーが誤ったログインを入力。ブラウザは再び資格情報の入力を求めます。
ユーザーがキャンセルを押す。ブラウザーは、ヘッダー401とともに送信されたカスタムエラーページを表示します。このページは、Firefoxを使用している場合、資格情報を入力するか、自動NTLM認証を許可する必要があることをユーザーに通知します。
Yeldarのコメントへの重要な追加:
リモート要求の応答メッセージを変更する場合(読み取り:非ローカルホスト)、構成ファイルに以下を追加する必要があります。
<system.webServer>
<httpErrors existingResponse="PassThrough"></httpErrors>
</system.webServer>
「パススルー」への応答を許可しない場合、リモートクライアントはデフォルトの"You do not have permission to view this directory or page"
を取得します。
私はこの情報を以下から入手しました: https://stackoverflow.com/a/17324195/3310441
Authorize属性のHandleUnauthorizedRequestメソッドをオーバーライドします。
例:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary (new {controller = "CustomError", action = "Unauthorized"}));
}