Forms auth cookie is cleared from response when AJAX web service call returns exception

Last post 11-05-2009 8:52 PM by mike.macarthur. 1 replies.

Sort Posts:

  • Forms auth cookie is cleared from response when AJAX web service call returns exception

    11-05-2009, 5:26 PM
    • Member
      8 point Member
    • mike.macarthur
    • Member since 12-17-2007, 2:51 PM
    • Scottsdale, AZ
    • Posts 13

    I have an ASP.NET AJAX application that uses forms authentication.  There are no postbacks in this application; all server functionality is on Page_Load or in web service calls made directly from the Javascript (via the AJAX toolscripts).  On each page load or web service call, the forms authentication ticket is updated by calling a simple utility method:

            public static FormsAuthenticationTicket RenewFormsAuthTicket()
            {            
                FormsAuthenticationTicket oldTicket = ((System.Web.Security.FormsIdentity)HttpContext.Current.User.Identity).Ticket;
                FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(oldTicket.Version + 1, oldTicket.Name, DateTime.Now, DateTime.Now.AddMinutes(((System.Web.Configuration.AuthenticationSection)System.Configuration.ConfigurationManager.GetSection("system.web/authentication")).Forms.Timeout.Minutes), oldTicket.IsPersistent, oldTicket.UserData);
                HttpCookie newCookie = new HttpCookie(System.Web.Security.FormsAuthentication.FormsCookieName, System.Web.Security.FormsAuthentication.Encrypt(newTicket));
                HttpContext.Current.Response.Cookies.Add(newCookie);
               
                return newTicket;
            }
    

    This "RenewFormsAuthTicket()" method is called from the web service base class's constructor so each individual web service doesn't have to worry about handling the session details.  It works great ... except when the web service throws an exception that is intended to go out to the AJAX error handler routine (in the Javascript). 

    What I found is that when the web service throws an exception, the new auth cookie that was added to the Response.Cookies collection in the above code does not make it into the response.  That makes sense to me, actually -- but I still need to keep the forms auth ticket timeout updated because the application is, in fact, being actively used.  In cases where the page has a list of items that are being submitted to a web service one at a time, the session sometimes does expire in the middle of making the web service calls, because the exceptions being returned from the web service calls are preventing updates to the authentication cookie.

    I thought a solution might be as simple as doing a Response.Flush right after updating the cookie with the above code.  This got the cookie updated just fine, but that resulted in the "On Success" Javascript callback function being invoked, and the actual web service exception was not handled.

    Does anyone have ideas on getting the forms auth cookie added to the response even when the web service throws an exception?

  • Re: Forms auth cookie is cleared from response when AJAX web service call returns exception

    11-05-2009, 8:52 PM
    Answer
    • Member
      8 point Member
    • mike.macarthur
    • Member since 12-17-2007, 2:51 PM
    • Scottsdale, AZ
    • Posts 13

    I found a solution so I'm posting for anyone else who may benefit.  Also, any suggestions are welcome.

    In the master page, I registered for the Sys.Net.WebRequestManager's completedRequest event.  This allowed me to call a page method to renew the forms auth ticket.  This call succeeds and the cookie is succssfully sent back in the response.  Code sample is below.

            //The On_WebRequestCompleted function will be called when EVERY AJAX page method or
            //web service call comes back from the call -- whether coming back to the Success callback
            //or to the Error callback.
            Sys.Net.WebRequestManager.add_completedRequest(On_WebRequestCompleted);
            function On_WebRequestCompleted(sender, eventArgs)   
            {
                /* NOTES:  sender.get_statusCode() will be '200' for normal completion; '500' for exception
                           sender.get_statusText() will be 'OK' for normal completion; 'Internal Server Error' for exception
                           sender.get_responseAvailable() is generally true here since a well-formed response was received
                */
                //If web service threw an exception, the auth cookie was removed from the response by the exception.
                //Therefore, a call is made here to update the session auth ticket to credit the activity to the session. 
                if (sender.get_statusCode() == 500 && sender.get_responseAvailable())
                {
                    PageMethods.KeepSessionAlive(onKeepSessionAliveComplete, onKeepSessionAliveFailed);
                }
            }
    


     

Page 1 of 1 (2 items)