12

This problem seems related to this post, but I was not able to infer a solution from the thread.

I noticed this code in an application I inherited (after noting in a log file that an exception was being eaten):

    protected void Session_End(object sender, EventArgs e)
    {
        try
        {
            FormsAuthentication.SignOut();
            FormsAuthentication.RedirectToLoginPage();
            //if (this.Context.Handler is IRequiresSessionState || this.Context.Handler is IReadOnlySessionState)
            //{
            //    FormsAuthentication.SignOut();
            //    FormsAuthentication.RedirectToLoginPage();
            //}
        }
        catch (Exception ex)
        {
            this.GetType().GetLogger().Error(ex);
        }
    }

I am wondering a few things. First, how is SignOut throwing a null reference exception? Is it an exceptional case, or am I doing something inherently wrong in my program? Next, what should I be testing against to head-off this exception before it is thrown?

15:51:57,288 [13] ERROR ASP.global_asax - System.NullReferenceException: Object reference not set to an instance of an object. at System.Web.Security.FormsAuthentication.SignOut() at MvcApplication.Session_End

Thanks

Community
  • 1
  • 1
Sean Anderson
  • 27,963
  • 30
  • 126
  • 237

1 Answers1

17

It's important to realize that Session_End doesn't get necessarily executed in the the context of an HTTP request. It may run when a session times out. You cannot send anything to the client at that time, because it simply isn't there anymore!

Consequently, you should not try to delete the forms authentication cookie in Session_End. If you want, you should do that sooner, when a "Sign Off" button is clicked somewhere in your application. If you need a user's forms authentication ticket to expire after a timeout occures, you should simply set the cookie expiration time appropriately (possibly equivalent to session timeout value) in the config file.

Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
  • Ahh... I had read something along those lines, but did not understand until I read it worded differently. Is that to say I should be validating against the existence of HttpContext.Current, or that eating the error message is an acceptable means of handling the 'randomness' of when Session_End fires? – Sean Anderson Jul 06 '11 at 23:29
  • @Sean You should use `Session_End` to remove the authentication cookie. It serves a different purpose and you can only assume you access server side stuff in that context. Besides, why would you need that in the first place? If you want the cookie to expire, just let it expire by setting its timeout. – Mehrdad Afshari Jul 06 '11 at 23:32
  • Hey, one more quick question. I was reading about the quirks of when Session_End is called and it states that (aside from timeouts) the only other way Session_End is called is through Session.Abandon. I found only one instance of Session.Abanadon in the solution I am working on. Do you know of other ways for Session_End to fire? Just looking to ensure that I don't break functionality. – Sean Anderson Jul 06 '11 at 23:42
  • @Sean No, I don't think there's any other way to run it by default, short of manually messing with stuff under the hood. – Mehrdad Afshari Jul 06 '11 at 23:47
  • Awesome! Some initial testing looks like this fixed the issue I was experiencing, as well. Quite happy. Thank you! – Sean Anderson Jul 06 '11 at 23:48
  • Hey. I have one more question about how the following scenario would be handled: User opens browser, navigates to page. FormsAUTH cookie is created and Session is started. The user closes the browser. The user opens the browser. A new Session is started (new browser instance..), but the old Session timeout has not been reached. As such, when they go back to the page..the FormsAUTH cookie still exists, but I am in a new Session. Is this true? – Sean Anderson Jul 07 '11 at 00:02
  • @Sean: If you pass `false` as the second argument to `FormsAuthentication.RedirectFromLoginPage`, it'll set a non-persistent cookie. – Mehrdad Afshari Jul 07 '11 at 00:06