简体   繁体   English

如何在ASP.NET中处理表单身份验证超时异常?

[英]How can I handle forms authentication timeout exceptions in ASP.NET?

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. 如果会话已过期且用户单击指向另一个webform的链接,则asp.net身份验证会自动将用户重定向到登录页面。

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. 例如:在gridviews中编辑链接,当使用带有文本框的AutoCompleteExtender并且应用程序尝试获取信息时,基本上,在每种情况下,当回发完成并且事件不是由asp.net身份验证自动处理时。

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? 更新:我刚刚针对我面临的具体问题创建了一个新问题: 如何使用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. 你真的需要挂钩ajax函数并查看返回状态代码,这有点困难。 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. 一种替代方法是使用基于以下内容的代码,该代码在页面生命周期的早期运行并执行ajax重定向到登录页面。 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. 否则你会试图拦截来自ajax和asp.net的返回代码,其中ajax是为你做的(即不是像jQuery这样的更手动的方法)你会失去这种易于检测。

http://www.eggheadcafe.com/tutorials/aspnet/7262426f-3c65-4c90-b49c-106470f1d22a/build-an-aspnet-session-timeout-redirect-control.aspx 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 快速入侵你可以直接在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! 因此,如果您将超时设置为一小时并在一个请求中发送25分钟,则会话将重置为一小时超时,表单身份验证票未触及并在35分钟后到期! 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: 您可以使用FormsAuthentication.Decrypt执行此操作 - 请参阅:

Read form authentication cookie from asp.net code behind 从asp.net代码后面读取表单身份验证cookie

Note that this code requires that upon login you set some session value - in this case its "UniqueUserId". 请注意,此代码要求在登录时设置一些会话值 - 在本例中为“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;
                        }
                    }
                }
            }
        }

If you're using Forms Authentication, the user will be redirected to the login page when the Forms Authentication ticket expires, which is not the same as the Session expiring. 如果您正在使用表单身份验证,则在表单身份验证票证到期时,用户将被重定向到登录页面,这与会话到期时不同。

You could consider increasing the Forms Authentication timeout if appropriate. 如果合适,您可以考虑增加表单身份验证超时。 Even to the extent of using a persistent cookie. 甚至到使用持久性cookie的程度。 But if it does expire, there's no real alternative to redirecting to the login page - anything else would be insecure. 但如果它到期,那么重定向到登录页面没有其他替代方案 - 其他任何东西都是不安全的。

One way to deal with Session timeouts is to use Session as a cache - and persist anything important to a backing store such as a database. 处理会话超时的一种方法是使用Session作为缓存 - 并保留对后备存储(如数据库)重要的任何内容。 Then check before accessing anything in Session and refresh if necessary: 然后在访问Session中的任何内容之前检查并在必要时刷新:

MyType MyObject
{
    get
    {
        MyType myObject = Session["MySessionKey"] as MyType
        if (myObject == null)
        {
            myObject = ... get data from a backing store
            Session["MySessionKey"] = myObject;  
        }
        return myObject;
    }
    set
    {
        Session["MySessionKey"] = value;
        ... and persist it to backing store if appropriate
    }
}

If you're using a master page or a base page, I would add some logic to one of the events in the page lifecycle to check whether the session is new: 如果您正在使用母版页或基页,我会在页面生命周期中的一个事件中添加一些逻辑来检查会话是否是新的:

protected void Page_Load(object sender, EventArgs e)
{
    if (Session.IsNewSession)
    {
        //do whatever you need to do
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在ASP.Net中延长表单身份验证时间? - How can I extend the Forms Authentication time in ASP.Net? ASP.NET 3.5表单身份验证超时 - Asp.net 3.5 forms authentication timeout 什么是Asp.net中的表单身份验证超时? - What is unit of Forms Authentication timeout in Asp.net? 表单身份验证和ASP.NET成员资格会话超时 - Forms Authentication & ASP.NET Membership Session Timeout ASP.NET Forms身份验证超时过期太早 - ASP.NET Forms authentication timeout expires too soon 如何处理 ASP.NET dbtransaction 超时 - how to handle ASP.NET dbtransaction timeout 如何对从C#控制台应用程序使用表单身份验证的ASP.NET WebAPI进行身份验证? - How can I authenticate to an ASP.NET WebAPI that is using Forms Authentication From a C# Console Application? 如何在Forms Authentication ASP.NET中将Cookie超时设置为少于1分钟? - How to set cookie Timeout less than 1 minute in Forms Authentication ASP.NET? 使用Active Directory角色和身份验证提供程序时,如何提供ASP.NET表单身份验证UX? - How can I provide an ASP.NET Forms Authentication UX while using Active Directory Role and Authentication providers? 如何处理asp.net表单身份验证调用后端服务的身份 - How to handle identity for asp.net forms authentication calling backend service
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM