我有一个网站,它实现了自己的基于表单的登录,并创建了一个这样的身份验证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无法使用会话。我可以将数据存储在应用程序缓存中(可能在键/值对中),但我不愿意这样做,因为应用程序缓存似乎不是放置此数据的“正确”位置。
我可能会把它放在应用程序缓存中,但在此之前,我想我会问,看看是否有人有更好的选择?
答案 0 :(得分: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);
}
}
}
}
它似乎工作正常(尽管到目前为止测试有限)。