我有一个位于 ASP.NET 表单身份验证后面的表单。到目前为止,实现遵循典型的“开箱即用”类型配置。
一页允许用户发布消息。如果用户长时间坐在该页面上撰写消息,它可能会超过身份验证会话到期时间。在这种情况下,帖子不会被记录……它们只是被重定向到登录页面。
我应该采取什么方法来防止长消息丢失的令人沮丧的事件?
显然,我可以让身份验证会话变得非常长,但是系统中还有其他因素不鼓励这种方法。 有没有办法让这个特定页面例外,只要它是回发,它就永远不会重定向到登录?
我有一个位于 ASP.NET 表单身份验证后面的表单。到目前为止,实现遵循典型的“开箱即用”类型配置。
一页允许用户发布消息。如果用户长时间坐在该页面上撰写消息,它可能会超过身份验证会话到期时间。在这种情况下,帖子不会被记录……它们只是被重定向到登录页面。
我应该采取什么方法来防止长消息丢失的令人沮丧的事件?
显然,我可以让身份验证会话变得非常长,但是系统中还有其他因素不鼓励这种方法。 有没有办法让这个特定页面例外,只要它是回发,它就永远不会重定向到登录?
我的同事使用 HttpModule 提出了解决此类问题的通用解决方案。
请记住,他决定在此特定应用程序中处理自己的身份验证。
开始:
他创建了一个 HttpModule 来检测用户何时不再登录。如果用户不再登录,他会获取该页面的 ViewState 以及所有表单变量并将其存储到一个集合中。之后,用户被重定向到登录页面,其中包含上一页的表单变量和隐藏字段中编码的 ViewState 信息。
用户成功重新验证后,会检查隐藏字段。如果该隐藏字段可用,则会使用旧帖子的表单变量和视图状态填充 HTML 表单。然后使用 Javascript 自动将此表单提交到服务器。
请参阅此相关问题,其中的答案几乎都是关于登录后保留值的相同概念的主题:
如果您不关心他们在发布时是否已登录(对我来说似乎有点不确定的安全性......),那么在 IHttpModule 中挂钩 HttpContext.PostAuthenticateRequest 将使您有机会使用 FormsAuthentication.SetAuthCookie 重新登录. 通过设置 HttpContext.User 可以类似地使用 FormsAuthenticationModule.Authenticate 事件:
// Global.asax
void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs e) {
// check for postback somehow
if (Request.Url == "MyPage.aspx" && Request.Form["MySuperSecret"] == "123") {
e.User = new GenericPrincipal(new GenericIdentity(), new string[] { });
}
}
当会话超时发生时,用户的会话(和页面信息)被释放,这意味着最终的回发将失败。正如其他人所建议的那样,有一些解决方法,但他们都假设您不关心该特定页面上的身份验证和安全性。
我建议使用 Ajax 每 10 分钟左右静默回发一次以保持其活动状态,或者按照您的建议增加会话的超时时间。您可以尝试在您的网络配置中创建一个特定于页面的部分,并在其中包含更长的超时时间。
我通过将表单值添加到数据库中处理了一次,由远程 IP 而不是用户 ID 标识。
( HttpContext.Request.UserHostAddress )
然后,登录后,您可以查看当前用户的 IP 地址在数据库中是否有一行,然后执行所需的操作。
迈克尔