问题描述
如果会话已过期并且用户单击指向另一个 Web 表单的链接,asp.net 身份验证会自动将用户重定向到登录页面.
但是,在某些情况下,用户不会点击其他网络表单的链接.例如:在 gridviews 中编辑链接,当使用带有文本框的 AutoCompleteExtender 并且应用程序尝试获取信息时,基本上,在每次回发完成并且事件不会由 asp.net 身份验证自动处理的情况下.
处理这些异常的最佳方法是什么?
更新:我刚刚修改了问题标题:表单身份验证超时,而不是初始会话超时.感谢您让我意识到这种差异.
更新:我刚刚针对我面临的具体问题创建了一个新问题:如何使用 UpdatePanel 处理因身份验证票过期而导致的异常?.令人惊讶的是,我没有找到太多关于它的信息.非常感谢您的帮助.
这就是为什么许多系统在页面上包含计时器来给出近似超时时间的原因.这对于交互式页面来说很难.确实需要钩住ajax函数,看返回状态码,有点难.一种替代方法是使用基于以下内容的代码,该代码在页面生命周期的早期运行并执行 ajax 重定向到登录页面.否则你会被困在试图拦截来自 ajax 的返回代码,并且在 ajax 为你完成的 asp.net 中(即不是像 jQuery 这样的更手动的方法)你会失去这种检测的便利性.
http://www.eggheadcafe.com/tutorials/aspnet/7262426f-3c65-4c90-b49c-106470f1d22a/build-an-aspnet-session-timeout-redirect-control.aspxp>
为了快速破解,您可以直接在 pre_init 中尝试http://forums.asp.net/t/1193501.aspx
编辑需要的是表单身份验证超时,而不是会话超时.表单身份验证超时的运行规模与会话超时不同.会话超时随着每个请求而更新.直到一半时间过去,表单身份验证票才会真正更新.因此,如果您将超时设置为一小时并在 25 分钟内发送一个请求,则会话将重置为一小时超时,表单身份验证票不会被触及并在 35 分钟内到期!要解决此问题,请同步会话超时和表单身份验证票.这样你仍然可以只检查会话超时.如果您不喜欢这样,那么仍然 - 执行以下操作并同步超时,然后解析身份验证票并读取其超时.您可以使用 FormsAuthentication.Decrypt 来做到这一点 - 请参阅:
从asp.net代码后面读取表单身份验证cookie
请注意,此代码要求在登录时设置一些会话值 - 在本例中为UniqueUserId".还要更改下面的登录页面路径以适合您的.
<代码>protected void Application_PreRequestHandlerExecute(对象发送者,EventArgs e){//只有在可用时才访问会话状态if (Context.Handler 是 IRequiresSessionState || Context.Handler 是 IReadOnlySessionState){//如果我们通过了身份验证并且我们在这里没有会话.. 重定向到登录页面.HttpCookie authenticationCookie = Request.Cookies[FormsAuthentication.FormsCookieName];if (authenticationCookie != null){FormsAuthenticationTicket authenticationTicket = FormsAuthentication.Decrypt(authenticationCookie.Value);if (!authenticationTicket.Expired){if (Session["UniqueUserId"] == null){//这意味着由于某种原因会话在身份验证票证之前过期.强制登录.FormsAuthentication.SignOut();Response.Redirect("Login.aspx", true);返回;}}}}}代码>
If the session has expired and the user clicks on a link to another webform, the asp.net authentication automatically redirect the user to the login page.
However, there are cases when the user does not click on links to other webforms. For example: edit link in gridviews, when using AutoCompleteExtender with textboxes and the application attempts to get the information, and basically, in every case when a postback is done and the event is not automatically handled by the asp.net authentication.
What is the best way to handle these exceptions?
UPDATE: I have just modified the question title: forms authentication timeout, instead of the initial session timeout. Thanks for making me aware of this difference.
UPDATE: I have just created a new question with the specific problem I am facing: How to handle exception due to expired authentication ticket using UpdatePanel?. Surprisingly, I have not found much information about it. I would really appreciate your help.
This is why many systems include timers on the page to give approximate timeout times. This is tough with interactive pages. You really need to hook ajax functions and look at the return status code, which is a bit difficult. One alternative is to use code based on the following which runs early in the page lifecycle and perform an ajax redirect to a login page. Otherwise you are stuck trying to intercept the return code from ajax and in asp.net where the ajax is done 'for you' (ie not a more manual method like jQuery) you lose this ease of detection.
http://www.eggheadcafe.com/tutorials/aspnet/7262426f-3c65-4c90-b49c-106470f1d22a/build-an-aspnet-session-timeout-redirect-control.aspx
for a quick hack you can try it directly in pre_init http://forums.asp.net/t/1193501.aspx
Edit what is wanted are for forms auth timeouts, not session timeouts. Forms auth timeouts operate on a different scale than session timeouts. Session timeouts update with every request. Forms auth tickets aren't actually updated until half of the time goes by. So if you have timeouts set to an hour and send in one request 25 minutes into it, the session is reset to an hour timeout, the forms auth ticket isnt touched and expires in 35 minutes! To work around this, sync up the session timeout and the forms auth ticket. This way you can still just check session timeouts. If you don't like this then still - do the below and sync up the timeouts and then parse the auth ticket and read its timeout. You can do that using FormsAuthentication.Decrypt - see:
Read form authentication cookie from asp.net code behind
Note that this code requires that upon login you set some session value - in this case its "UniqueUserId". Also change the login page path below to fit yours.
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
//Only access session state if it is available
if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState)
{
//If we are authenticated AND we dont have a session here.. redirect to login page.
HttpCookie authenticationCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authenticationCookie != null)
{
FormsAuthenticationTicket authenticationTicket = FormsAuthentication.Decrypt(authenticationCookie.Value);
if (!authenticationTicket.Expired)
{
if (Session["UniqueUserId"] == null)
{
//This means for some reason the session expired before the authentication ticket. Force a login.
FormsAuthentication.SignOut();
Response.Redirect("Login.aspx", true);
return;
}
}
}
}
}
这篇关于如何在 ASP.NET 中处理表单身份验证超时异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!