最近遇到一个问题,就是部分低端手机登陆后Form认证成功Cookie 丢失,
无奈之下用办法尝试解决保存用FormsAuthentication.SetAuthCookie() 后直接获取 HttpContext.Current.User.Identity.IsAuthenticated 为True.
由于Form 认证后加密及时把信息保存在Cookie中,本次请求无法获取到登录状态,必须等刷新后吧数据Response 后到下一个request中 才可以后期到Request. IsAuthenticated 的值。
目前现状就是这样,问题是部分手机自带浏览器会把form认证Cookie信息丢失,为了兼容这部分手机,
1、登录信息保存在在数据库或文件缓存中,然后把加密后的索引值负责url 中。通过判断url然后获取缓存数据判断用户登录。
2、由于项目都是通过form认证判断用户登录的,如果所有判断会耗费大量时间和精力,必须实现在同一个请求页面实现 FormsAuthentication.SetAuthCookie() 用户登录信息的缓存,
同时还必须获取用户认证信息 Request. IsAuthenticated 。
3、由于在同一个请求中保存认证的Cookie信息还没有Response到客户端,根本无法获取Request.IsAuthenticated 值,查看HttpRequest源码可以发现获取获取值 context.User.Identity.IsAuthenticated 值。
get {
if (context.User == null || context.User.Identity == null)
return false;
return context.User.Identity.IsAuthenticated;
}
}
我们可以手动生产一个用户安全认证信息,方便与如用户控件LogView识别(LogView控件依赖form认证后触发viewchange事件),我们直接给用户信息保存到Context.User 如:
Context.User = new GenericPrincipal(new GenericIdentity(userName, "Forms"), null);
此时,完成更新form中保存用户信息后, HttpContext.Current.User.Identity.IsAuthenticated 的值为True 了。 loginView 会自动触发转换为登录用户状态,
当然 后可以使用其他方法实现,如下需要用户其他更完整更新用户信息可以参考如下:
{
System.Web.HttpCookie authCookie =
System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = null;
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
if (authTicket != null && !authTicket.Expired)
{
FormsAuthenticationTicket newAuthTicket = authTicket;
if (FormsAuthentication.SlidingExpiration)
{
newAuthTicket = FormsAuthentication.RenewTicketIfOld(authTicket);
}
string userData = newAuthTicket.UserData;
string[] roles = userData.Split(',');
Context.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(newAuthTicket), null);
System.Web.HttpContext.Current.User =
new System.Security.Principal.GenericPrincipal(new FormsIdentity(newAuthTicket), roles);
}
}
}