1

独自のフォーム ベースのログインを実装し、次のような認証 Cookie を作成する Web サイトを持っています。

    FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userID, DateTime.UtcNow, expiration, isPersistent, userFunctions);
    HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket));
    cookie.Expires = expiration;
    HttpContext.Current.Response.Cookies.Add(cookie);

変数「userFunctions」には、ユーザーがメンバーであるロールのカンマ区切りのリストが含まれています。

私の Global.asax ファイルでは、次の方法でこれらのユーザー関数を取得しています。

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    if (HttpContext.Current.User != null)
    {
        if (HttpContext.Current.User.Identity.IsAuthenticated)
        {
            if (HttpContext.Current.User.Identity is FormsIdentity)
            {
                FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;

                string[] roles = id.Ticket.UserData.Split(',');
                HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(id, roles);
            }
        }
    }
}

これはすべてうまくいっています。または、まったく新しいユーザーの束のためにそれを変更しなければならなくなるまででした. 新しいユーザーの問題は、「userFunctions」変数が非常に長くなる可能性があり、Cookie に保存するには長すぎることです (サイズは 4k 程度に制限されています)。

「userFunctions」をセッションに保存するようにコードを変更しますが、セッションは Application_AuthenticateRequest で使用できません。データをアプリケーション キャッシュに格納することもできますが (おそらくキーと値のペアで)、アプリケーション キャッシュはこのデータを配置するのに「適切な」場所ではないように思われるため、それをためらっています。

私はおそらくそれをアプリケーションキャッシュに入れることになるでしょうが、そうする前に、誰かがより良い代替手段を持っているかどうか尋ねてみようと思いましたか?

4

1 に答える 1

1

Sessionを使用してユーザーロールを保存することはできず(承認が行われる前にユーザーロールを取得できないため)、ページ要求ごとにデータベースにアクセスする費用をかけたくなかったため、ロールをに保存することになりました。アプリケーションキャッシュ:

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    if (HttpContext.Current.User != null)
    {
        if (HttpContext.Current.User.Identity.IsAuthenticated)
        {
            if (HttpContext.Current.User.Identity is FormsIdentity)
            {
                FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;

                string[] roles;
                string cachedRoles = (string)HttpContext.Current.Cache.Get("UserFunctions" + id.Name.ToLower());
                if (cachedRoles == null)
                {
                    // Reload UserFunctions and add back in to Cache.

                    cachedRoles = [...code to get UserFunctions from database...];

                    HttpContext.Current.Cache.Insert("UserFunctions" + id.Name.ToLower(), cachedRoles, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 20, 0), System.Web.Caching.CacheItemPriority.NotRemovable, null);

                }

                roles = cachedRoles.Split(',');

                HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(id, roles);
            }
        }
    }
}

それは問題なく動作しているようです(これまでのところテストは限られていますが)。

于 2012-12-05T13:37:20.300 に答える