0

設定

カスタムフォーム認証を使用しています-すべて標準的なものです。

アカウントコントローラーのログインアクションで、

  • データベースに対してユーザーの詳細を確認します
  • 成功した場合は、フォーム認証チケットを作成します
  • ログインしたメンバーのデータベースの行 ID をチケットの UserData に格納します
  • チケットを暗号化する
  • チケットを Cookie に保存する
  • Cookie を Reponse.Cookies コレクションに追加します。
  • ホームコントローラーでのインデックスアクションにリダイレクト

AuthenticateRequest イベントのグローバル asax にハンドラーを登録しました。私のハンドラーでは、

  • HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; から Cookie を取得します。
  • Cookie が存在する場合、Cookie 内のフォーム認証チケットの値を復号化します
  • 認証チケット UserData に格納されている Id を使用して、データベースからユーザーの詳細を取得します。
  • カスタム プリンシパルを作成し、ユーザー (カスタム LoggedInUser プロパティを持つ) をデータベースから取得したユーザーに設定します。
  • HttpContext.Current.User をカスタム プリンシパルに設定します。

問題

ログイン後にホームページのリクエストをデバッグすると、global.asax の AuthenticateRequest ハンドラがページ リクエストごとに複数回ヒットすることがわかりました。HttpContext.Current.Request.Path を確認しましたが、これは、ページ上の各リソース (事実上、すべての HTTP GET) が認証要求を発行しているためです。GET jquery.js、GET logo.png など...

質問

最初に処理された AuthenticateRequest で、db に移動し、HttpContext.Current.User をカスタム プリンシパルに設定します。AuthenticatRequest を起動させる後続の HTTP GET のためにデータベースにアクセスしないようにするための良い方法は何でしょうか。実際には、ユーザーがブラウザを閉じるか、認証チケットの有効期限が切れるまで、一度だけ認証を行います。

ティア

4

1 に答える 1

1

AuthenticateRequestGlobal.asax でメソッドを使用する代わりに、グローバル アクション フィルターを作成することをお勧めします。このように、アクション フィルターは、何らかのアクションを実行してユーザーを設定する前にのみ適用されます。実際、カスタム[Authorize]属性はそれを達成するための最良の方法です:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }

        // TODO: go ahead and work with the UserData from the authentication cookie
        // basically all the steps you described for your AuthenticateRequest handler
        // except for checking the presence of the forms authentication cookie because
        // we know that at this stage it exists and the user was successfully authorized

        return true;
    }
}
于 2012-06-12T16:03:25.510 に答える