By aleafonso


2011-09-28 16:31:25 8 Comments

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.

3 comments

@Adam Tuliper - MSFT 2011-09-28 17:05:52

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;
                        }
                    }
                }
            }
        }

@aleafonso 2011-09-29 10:24:28

Hi Adam. I have just had a look at your recommended posts. However, I think these solution could work for session timeouts. My fault, I should have made clear my question was about the forms authentication "ticket" timeout. I have just updated it accordingly. Any other idea on how to solve this issue? Thanks a lot for sharing

@aleafonso 2011-09-30 16:30:25

Hi again Adam. Where should I add this procedure? I first thought I should add it to the MasterPage since all the pages use the same one but when I clicked on the GridView Edit link it did not catch the event. I also tried adding the code the webform but, surprisingly, it did not catch the event either. I wonder if this has something to do with the partial call caused by the UpdatePanel. So, where can I add the code?

@aleafonso 2011-10-03 08:04:03

Hi Adam. I have just tried this solution. However, if the ticket has expired and I click on the Edit link in a GridView (whithin an UpdatePanel), the event is not handled by "Application_PreRequestHandlerExecute" since it breaks before it gets there (I assume). I know the error is related to the ticket expiration as it does not break when the ticket has not expired. Any other idea will be more than welcome!

@Adam Tuliper - MSFT 2011-10-19 04:53:42

you are saying when the ticket has expired, PreRequestHandlerExecute never executes?

@Softlion 2011-10-25 15:50:18

Response.Redirect does not work for ajax calls. You need to detect ajax calls and do special processing, for example return a 409 and add a X-Redirect header containing the url to redirect to. On javascript side using jQuery, set a global error handler and handle the 409 special case so it redirects to the content of the X-Redirect header.

@Adam Tuliper - MSFT 2011-10-26 06:45:09

@Softion that is not entirely accurate, there is a much easier way to set this up in web.config if I recall without having to do the checks you mentioned. I'll update this when not on phone but it is important to bring up though thanks.

@Adam Tuliper - MSFT 2011-10-26 14:34:27

@Softion note the web.config method here ranafaisal.wordpress.com/2008/06/02/… using the ScriptModule

@aleafonso 2011-10-28 11:40:10

Thank you for the answer @Adam. At the beginning I was confused because in Debugging mode it breaks before the error is handled by the PreRequestHandlerExecute. Now I have tried this without Debugging and it actually redirects me to the login page. Regards,

@aleafonso 2011-10-28 15:52:45

I get a popup from Visual Studio: Microsoft JScript runtime error: Sys.ArgumentNullException: Value cannot be null. Parameter name: array --- In the file: ScriptResource.axd...................... In this set of instructions: $type.indexOf = function Array$indexOf(array, item, start) { var e = Function._validateParams(arguments, [ {name: "array", type: Array, elementMayBeNull: true}, {name: "item", mayBeNull: true, optional: true}, {name: "start", mayBeNull: true, optional: true} ]); if (e) throw e; return indexOf(array, item, start);

@Softlion 2011-11-02 17:38:42

@Adam Tuliper: the scriptModule works only with Microsoft Ajax. It does not work with ASP.NET MVC / jQuery.

@Adam Tuliper - MSFT 2011-11-03 04:25:44

@Softion sure but this post was not tagged MVC and was for web forms.

@aleafonso 2011-11-03 17:27:08

@AdamTuliper I am using web forms! Certainly I use jQuery (most of the time jQuery-ui). I am not too sure that this is why I am getting the error, since it may occur when I click on a link in the gridview, and jquery is not involved at all.

@Adam Tuliper - MSFT 2012-01-16 15:26:43

ah since you are using jquery here I believe you need to set a response code on the server side (instead of a redirect). Your jQuery ajax method must check this. Im not sure about the control of tje jquery ui call you have and if you can set a 'redirect' value on your json. if you cant, check out brians answer on there to detect the text response from the redirect I had in the code above.

@Joe 2011-09-28 18:32:22

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. 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. Then check before accessing anything in Session and refresh if necessary:

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
    }
}

@aleafonso 2011-09-29 10:17:25

Hi Joe. I am indeed using Forms authentication and I've just updated the question accordingly. During the login, if the user wants to be remembered, I create a persistent cookie, otherwise, I just create the authentication "ticket". If the authentication ticket has expired and the user requests another webform it gets redirected to the login page (which is alright). My problem comes when the users have waited too long to do any event (other than page requests) involving a postback and the ticket has already expired. What can I do in this case? Thanks a lot for your time

@James Johnson 2011-09-28 18:07:28

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
    }
}

@Wiktor Zychla 2011-09-28 18:29:25

I believe that saying "Session timeout" he actually means "authentication session timeout" like timing out of the forms cookie. And your suggestion would be rather not helpful for detecting that the authentication is no longer valid.

@aleafonso 2011-09-29 07:39:39

That's exactly what I meant. Thanks for clarifying @Wiktor. Sorry for the misunderstanding James.

@JohnH 2017-01-26 14:38:17

A problem with adding forms authentication logic to the master page's code is that this logic is executed after the content page's code.

Related Questions

Sponsored Content

11 Answered Questions

[SOLVED] How to properly ignore exceptions

33 Answered Questions

[SOLVED] How do you assert that a certain exception is thrown in JUnit 4 tests?

25 Answered Questions

[SOLVED] How can I safely create a nested directory?

5 Answered Questions

[SOLVED] asp.net cookies, authentication and session timeouts

2 Answered Questions

[SOLVED] Forms Authentication Timeout vs Session Timeout

2 Answered Questions

[SOLVED] ASP.NET Forms Authentication timeout

1 Answered Questions

[SOLVED] Forms Authentication Timeout Logging

4 Answered Questions

Sponsored Content