Simple Fix for ASP.NET FormsAuthentication Redirect when using AJAX
Posted in ASP.NET, C#, MVC, jQuery by JarrettV on 9/21/2012 5:39:00 AM - CSTThere is one paticular annoying "feature" of ASP.NET forms authentication module that has kicked my butt many times. When a user loads a page but their session has expired, the module will take over the request and return a 302 redirect to the login page rather than the appropriate 401 unauthorized.
Specification of the correct behaviour has been part of the HTTP standard for more than 15 years now. HTTP 1.1, RFC 2616 (and before that, HTTP 1.0, RFC 1945) specify the correct behavior in sections 10.4.2 and 9.4 respectively (the verbiage hasn't changed significantly):
This "feature" has always been broken in ASP.NET and it has caused me countless hours of research and workarounds. Others have also dealt with the problem:
- Prevent Forms Authentication Login Page Redirect When You Don't Want It
- Basic Authentication with WCF Web API hosted in IIS / Getting a 404 - Disable Forms Authentication Redirection
- Prevent forms auth from redirecting to login page in RESTFul WCF
- AJAX and FormsAuthentication, how prevent FormsAuthentication overrides HTTP 401?
- How to Handle Forms Authentication Timeout During an AJAX Request
- How to intercept 401 from Forms Authentication in ASP.NET MVC?
Back in 2008, I used the HttpModule workaround as decribed in many of the above posts. I've also utilized an Application_OnError workaround. Unfortunately, many of these solutions require too much code, additional config, and/or tradeoffs.
I would prefer a fix directly to forms authentication, but Microsoft still hasn't addressed the problem. We could replace forms authentication with something like AppHarbor.Web.Security or MADAM. However, this can be scary to those who are unfamiliar with exercising options outside of those provided by Microsoft.
So that brings me to point of this post. How can we KISS and still fix the damn problem?
Add this to Global.asax.cs to fix the broken FromsAuthentication redirect behavior. This code will reset the 302 back to 401 for AJAX requests.
Add this javascript to your layout so that anytime you use jQuery ajax, get, or post, the client will detect the 401 and reload the page. This will cause the browser to redirect to login page.
That's all. Problem fixed with very few lines of code.
Comments
Posted by Carl Sharman on 1/16/2013 8:38:39 AM - CST
Posted by mcessna on 2/27/2013 3:22:54 PM - CST
Posted by Steven on 5/1/2013 8:22:03 AM - CST
I'm curious, though, why your javascript doesn't just handle the 302 error in the first place?
Posted by prapoorna on 8/8/2013 3:43:01 AM - CST
Posted by www.google.com/accounts/o8/id?id=AItOawleqJU_jSQqRQY9hylnMDb-hebf6fXzdck on 10/7/2013 12:27:34 PM - CST
Posted by Mark on 2/19/2014 11:06:34 PM - CST
Trackback from Burbujas en .NET on 2/25/2014 10:45:46 AM - CST
ASP.NET MVC, [Authorize] y jQuery.load
Muy buenas! Estreno el blog este 2014… dios a finales de Febrero! A ver, si empezamos a retomar el ritmoPosted by Soham on 5/21/2014 4:11:38 AM - CST
if (FormsAuthentication.IsEnabled && context.Response.StatusCode == 302 && context.Request.IsAjaxRequest() && !context.Request.IsAuthenticated) ....
Posted by Emil G on 4/22/2015 3:12:00 AM - CST