Question

In my ASP.NET MVC4 application, I'm using forms authentication. One view in the app needs to get some string data via a jQuery post() call. I wrote an action that returns string. Everything works fine until the forms authentication ticket expires. After expiration, the AJAX call to the string action results in following:

  • The code within the action does not get executed
  • The action returns a HTTP 200 and not a 401
  • The action returns HTML of the Login view as string
  • Because 200 status was returned and not 401, the control ends up in jqXHR.done() instead of jqXHR.fail()

Is this expected behavior? Can I do something to make the action return a 401? Or is there something else I should be doing to handle this?

Was it helpful?

Solution 2

Yes this is the expected behaviour.

In Asp.Net 4.5 the HttpResponse.SuppressFormsAuthenticationRedirect Property has been added. But the default behaviour is still a redirect to the login page. From MSDN:

By default, forms authentication converts HTTP 401 status codes to 302 in order to redirect to the login page. This isn't appropriate for certain classes of errors, such as when authentication succeeds but authorization fails, or when the current request is an AJAX or web service request. This property provides a way to suppress the redirect behavior and send the original status code to the client.

You could use this property or try the following workaround from this answer:

protected void Application_EndRequest()
{
     if (Context.Response.StatusCode == 302 && Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
    {
        Context.Response.Clear();
        Context.Response.StatusCode = 401;
    }
}

Or you could take a look at this question and answers: Forms authentication: disable redirect to the login page and pick a method that suits you to return a 401.

OTHER TIPS

Putting the code in Application_EndRequest() did not work for me. Here is what works in my case:

    protected void Application_BeginRequest()
    {
        HttpRequestBase request = new HttpRequestWrapper(Context.Request);
        if (request.IsAjaxRequest())
        {
            Context.Response.SuppressFormsAuthenticationRedirect = true;
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top