【发布时间】:2012-02-08 21:27:13
【问题描述】:
在我们的应用程序中,我们实现了基于角色的表单身份验证。这已使用 RoleModule 处理,我们将角色数据保存在 cookie 中,
每次我们从cookie中读取数据并实例化IPrincipal对象。这段代码在Application_OnPostAcquireRequestState方法中执行:
HttpApplication application = source as HttpApplication;
HttpContext context = application.Context;
if (context.User.Identity.IsAuthenticated &&
(!Roles.CookieRequireSSL || context.Request.IsSecureConnection))
{
//Read the roles data from the Roles cookie..
context.User = new CustomPrincipal(context.User.Identity, cookieValue);
Thread.CurrentPrincipal = context.User;
}
这会初始化context.User 对象。每次向服务器发出请求时,都会使用上述流程对用户进行身份验证。
在Application_EndRequest 中,我们使用当前主体对象数据更新角色cookie。
在我们的Global.asax 页面中有FormsAuthentication_OnAuthenticate 方法,我们在其中读取cookie,更新cookie,并更新
票过期了。另外,在这个方法中,如果票据过期,我们会尝试在会话对象中设置用户名值。
FormsAuthentication oldTicket = FormsAuthentication.Decrypt(context.Request.Cookies[FormsAuthentication.FormsCookieName].Value);
if(oldTicket != null)
{
if(oldTicket.Expired)
{
try
{
HttpContext.Current.Session["UserName"] = userName;
}
catch
{
//Log error.
}
FormsAuthentication newTicket = new FormsAuthenticationTicket(oldTicket.Version, oldTicket.Name, DateTime.Now,
DateTime.Now.AddMinutes(30), oldTicket.IsPersistent, oldTicket.UserData);
string encryptedTicket = FormsAuthentication.Encrypt(newTicket);
HttpCookie httpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
if (isPersistent)
{
httpCookie.Expires = DateTime.Now.AddMinutes(300);
}
}
这是我们在 web.config 中的表单设置:
<forms defaultUrl="Default.aspx" domain="" loginUrl="Login.aspx" name=".ASPXFORMSAUTH" timeout="20" slidingExpiration="true" />
会话超时为 20 分钟。
问题:如果用户闲置超过 30 分钟(即 FormsAuth 票证续订时间),context.User.Identity.IsAuthenticated 中的值
角色模块为false,context.User设置为NULL。现在,当用户请求一个页面时,他将被重定向到登录页面。但是,那
饼干还在。如果再次,用户尝试请求页面,context.User.IsAuthenticated 属性设置为true,用户将被带到
相应的页面。另外,在FormsAuthentication_OnAuthenticate 方法中,当我尝试设置会话值时,它会抛出一个错误,因为会话对象是NULL。
我想在这里实现的是,在持久cookie的情况下,在auth票超时后,用户不应该被注销,即用户应该 重新认证。
我怎样才能做到这一点?
如果我没记错的话,设置context.User应该可以解决问题,但是我该怎么做呢?
其他信息:
票证到期后,我尝试请求页面,事件查看器显示错误消息:
Event code: 4005
Event message: Forms authentication failed for the request. Reason: The ticket supplied has expired.
Event time: 08-02-2012 20:02:05
Event time (UTC): 08-02-2012 14:32:05
Event ID: 048e3238ade94fd6a7289bac36d130ef
Event sequence: 76
Event occurrence: 2
Event detail code: 50202
Process information:
Process ID: 21692
Process name: w3wp.exe
Account name: IIS APPPOOL\ASP.NET v4.0 Classic
我使用的是标准机器密钥设置,存储在 web.config 中,而不是自动生成的。此外,我检查了所有错误的进程 ID 及其相同。
【问题讨论】:
标签: asp.net cookies forms-authentication httpmodule formsauthenticationticket