1

我有一个网站,它实现了自己的基于表单的登录,并创建了一个像这样的身份验证 cookie:

    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 回答