トップ回答者
IIS 7.5+ASP.NETのフォーム認証Webサイトに特定のUser-Agentでアクセスすると401.2発生

質問
-
IIS 7.5+ASP.NETで動作するフォーム認証を設定したWebサイトに対し、ログインしてからでないとアクセスできないページにアクセスしたとき、要求ヘッダのUser-Agentのが特定の値(主に携帯電話のユーザーエージェント)だとログイン用のページにリダイレクトせず401.2エラーとなるケースを確認しました。たとえばtelnetでUser-Agentに次の値を指定すると再現します(これはNTTドコモ様が提供するiモードシミュレータIIの値です):
DoCoMo/2.0 ISIM60(c500;TB;W24H16)
回避策を模索していますが、まだうまい手が見つかりません。アドバイス等いただければたいへんありがたく存じます。
回答
すべての返信
-
回避すればいいのでしょうか? もっと言うと挙げられているシミュレータ上でのみ動作すればいいのでしょうか? 実機でも動作することが目的なのではと思いますが…。
ASP.NETではUser-Agentを元にブラウザの持つ機能を把握し、その機能範囲内で動作する ようになっています。ASP.NETのバージョンにもよりますが、2.0~3.5であれば
C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers\docomo.browser
にその情報があり、このファイルの一番下に使用されているシミュレータも定義されています。これを読むとcookiesもsupportsRedirectWithCookieもtrueなのでエラーになっている原因はちょっとわかりません。問題はシミュレータ以外のもっと古い機種だとこれらのオプションもfalseなことです。ログイン以外にもいろいろと問題が出るように思います。
- 回答の候補に設定 山本春海 2011年1月31日 7:52
-
コメントありがとうございます。
もちろん根本的に解決したいのですが、手がかりが少ないため対策のターゲットも定められない状態です。最終的な目的は実機での動作です。
ASP.NETブラウザ登録ツール(aspnet_regbrowsers.exe)でランタイム ブラウザ機能アセンブリをグローバル アセンブリ キャッシュからアンインストールしても状況は変わりません。
http://msdn.microsoft.com/ja-jp/library/ms229858%28v=vs.80%29.aspx
cookieは利用しませんし、古い機種は対象外とすることもできるので普通に動けばなんとかできるのですが、入り口で引っかかってしまっています。
-
マネージパイプラインモードに「クラシック」を指定したアプリケーションプールを指定すると発生しないことを確認しました。
私も同様の現象が発生していまして、この記事も参考にさせていただいています。
マネージ パイプライン モードを「クラシック」にすると、ASP.NETの「.NET の承認規則」による Authorize が行われない場合がありました。おそらく、行われなかったから、401.2エラーも発生しなかったのはないかと思います。IISの「承認規則」は未検証です。
そこで、PostAuthenticateRequest イベント時に以下のように、自分でリダイレクト処理を書いて、実機でもエミュレータでも回避できました。
if (!Context.SkipAuthorization) { bool isAuthrised = UrlAuthorizationModule.CheckUrlAccessForPrincipal(Request.Path, Context.User, Request.HttpMethod); if (!isAuthrised) { FormsAuthentication.RedirectToLoginPage(); Response.End(); } }
Response.End()がないと、次の AuthoriseRequest 系のイベントに突入して、401.2エラーが発生しました。
ASP.NETの「.NET の承認規則」は、system.web/authorizationIISの「承認規則」は、system.webServer/security/authorizationの設定という意味です。
影響はないと思いますが、すべてのファイルをフォーム認証で保護するために、system.webServer/modules の runAllManagedModulesForAllRequests 属性を true にして、FormsAuthentication を再定義しています。
昨日書いたばかりの未リリースのコードなので、何か間違いがあったらすみません。 -
「.NET の承認規則」は、UrlAuthorizationModule.OnEnter メソッドで実現しているようで、OnEnter はAuthorizeRequest イベントに紐づけられています。
このメソッドの中で、条件が揃えば、Response.StatusCode = 401 を設定しています。
その後、EndRequest イベントに紐付けっれたフォーム認証のFormsAuthenticationModule.OnLeave メソッドで、401だった場合は設定した LoginUrl にResponse.Redirect するようです。
Redirect メソッドで302に書き換わることで、万事うまくいくはずでしたが、結果的にどこかうまくいかない理由は、わかりませんでした。
ですので、AuthenticateRequest が終わって、Context.User が割り当てられた後で、かつ、AuthorizeRequest が始まる前、というのが処理するのが相応しいイベントではないかと思いました。
実際のところは 401で終わらなければ良いので、処理しても良いタイミングはもっと幅広いです。