Global.asax.Application_AuthenticateRequest で割り当てられた後に Context.User がロールを失う
-
09-06-2019 - |
質問
asp.net (3.5) アプリケーションでフォーム認証を使用しています。また、ロールを使用して、どのユーザーがアプリのどのサブディレクトリにアクセスできるかを定義しています。したがって、web.config ファイルの関連セクションは次のようになります。
<system.web>
<authentication mode="Forms">
<forms loginUrl="Default.aspx" path="/" protection="All" timeout="360" name="MyAppName" cookieless="UseCookies" />
</authentication>
<authorization >
<allow users="*"/>
</authorization>
</system.web>
<location path="Admin">
<system.web>
<authorization>
<allow roles="Admin"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
私が読んだ内容によると、これにより、Admin ディレクトリにアクセスできるユーザーは、認証され、Admin ロールが割り当てられたユーザーのみになることが保証されます。
ユーザー認証、認証チケットの保存、およびその他の関連する問題はすべて正常に機能します。web.config ファイルからタグを削除すると、すべてが正常に動作します。問題は、管理者ロールを持つユーザーのみが管理者ディレクトリにアクセスできるように強制しようとしたときに発生します。
これに基づいて MS KB の記事 同じ情報を提供する他の Web ページとともに、次のコードを Global.asax ファイルに追加しました。
protected void Application_AuthenticateRequest(Object sender, EventArgs e) {
if (HttpContext.Current.User != null) {
if (Request.IsAuthenticated == true) {
// Debug#1
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(Context.Request.Cookies[FormsAuthentication.FormsCookieName].Value);
// In this case, ticket.UserData = "Admin"
string[] roles = new string[1] { ticket.UserData };
FormsIdentity id = new FormsIdentity(ticket);
Context.User = new System.Security.Principal.GenericPrincipal(id, roles);
// Debug#2
}
}
}
ただし、ログインしようとすると、Admin フォルダーにアクセスできません (ログイン ページにリダイレクトされます)。
問題をデバッグしようとして、リクエストをステップ実行し、上記の Debug#1 とマークされた行で Context.User.IsInRole("Admin") を実行すると、false が返されます。Debug#2 行で同じステートメントを実行すると、それは true になります。したがって、少なくとも Global.asax に関する限り、ロールは適切に割り当てられています。
Global.asax の後、実行はログイン ページに直接ジャンプします (ロールがないため、管理フォルダーへのページの読み込みが拒否されるため)。ただし、ログインの Page_Load の最初の行で同じステートメントを実行すると、false が返されます。そのため、Global.asax の Application_AuthenticateRequest と、制限されたディレクトリに WebForm を最初にロードした後のどこかで、ロール情報が失われ、認証が失敗します (注:Page_Load では、適切な認証チケットが依然として Context.User.Id に割り当てられています (ロールのみが失われています)。
何が間違っているのでしょうか?どうすれば正しく動作させることができますか?
アップデート:私が入力したのは、 以下の解決策
解決
ここに問題と解決策がありました:
開発の初期に、[Web サイト] メニューに移動して [Asp.net 構成] をクリックしました。これにより、次の行が web.config に追加されました。
<system.web>
<roleManager enabled="true" />
</system.web>
その時点から、アプリは、FormsAuthentication ロールではなく、Asp.net サイト マネージャーを通じてロールを実行していると想定するようになりました。したがって、実際の認証とロールのロジックが正しく設定されていたにもかかわらず、失敗が繰り返されました。
この行が web.config から削除された後は、すべてが完全に機能しました。
他のヒント
これは単なるランダムショットですが、管理者の承認順序のせいでブロックされているのでしょうか?おそらく、すべて拒否とすべての管理者を切り替えてみるとよいでしょう。
拒否によって上書きされる場合に備えて。
(ここにコードサンプルがありましたが、表示されませんでした。