1

the problem is that if the auth cookie has expired and the user clicks on a link that should open a popup using $.get than i get the login screen in the popup (same masterpage in another masterpage) instead of redirecting the whole page to the login screen

anybody knows how to fix this ?

Omu
  • 69,856
  • 92
  • 277
  • 407
  • Do you want the user to be redirected to the login page if she clicks on a link and the auth cookie is expired? Please clarify the question. – Anurag Jan 15 '10 at 09:51
  • 1
    yes, I want the user to be redirected when he clicks on a link, and this is what usually happens, but when he clicks on a link that is jquery $.get wich returns a PartialViewResult into a popup than i get the login screen into the popup – Omu Jan 15 '10 at 10:02

5 Answers5

3

When you make a request after your login session has expired ASP.NET will automatically do a 302 redirect to your login action instead of returning a 401 "Unauthorized". The browser will quietly follow the redirect (even during an AJAX request) and make a second request to bring down the login page. There's no way that I am aware of to detect or prevent this redirect in Javascript and there's no way of prevent the redirect server-side without reimplementing the entire FormsAuthenticationModule.

However, jQuery inserts an HTTP header

X-Requested-With=XmlHttpRequest

when making Ajax calls. The Request.IsAjaxRequest() method in ASP.NET MVC can be used to detect the presence of this header.

What we do in our site is put

if (Request.IsAjaxRequest()) { return new HttpUnauthorizedResult(); }

into our /auth/login action so that a 401 error is returned instead of the login page HTML if /auth/login is called during an AJAX call. We then detect the 401 in Javascript and redirect to the login page manually.

Unfortunately Firefox (as of 3.5) and Opera (as of ~9.something) do not maintain the X-Requested-With header in the second request after a redirect, so IsAjaxRequest() returns false in this situation when these browsers are being used. This wasn't a big issue for us but its something to keep in mind.

Aidan Boyle
  • 1,431
  • 1
  • 8
  • 7
  • Here's what I do to overcome redirect issue: http://stackoverflow.com/questions/1588589/firefox-does-not-preserve-custom-headers-during-ajax-request-redirect-an-asp-net. It may fail to work on old IIS versions due to read-only headers; thus in the project I use custom flag in TempData and custom IsAjaxRequest like this: return controller.ControllerContext.HttpContext.Request.IsAjaxRequest() || controller.TempData.ContainsKey("__isajaxrequest"). – queen3 Jan 15 '10 at 13:26
2

I don't know what you do with the results of your $.get operation but you could do one of the following:

  • Detect when your page is called through Ajax, and return a graceful error message

  • Detect when your page is called through Ajax, and return a piece of JavaScript to redirect the whole page to the login page (location.href=...)

Check out this question (the 2nd answer, preferably, mentioning the header) to find out how to detect whether a call was made using AJAX.

Community
  • 1
  • 1
Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • i have an action method that returns PartialView, the $.get calls this action method and puts this result into a div which is shown after this as a popup using jquery – Omu Jan 15 '10 at 09:56
  • Right. I'm not familiar with ASP/.net but the basic workings should be the same. Your login page should react if called through AJAX and return the right content, a script snippet changing the location should do just fine. – Pekka Jan 15 '10 at 09:59
2

ASP.NET MVC has the following property on it's Request object:

Request.IsAjaxRequest()

This will (amongst other things) checks for the existence of the X-Requested-With header, and a value of XMLHTTPRequest. Checking this, along with checking for IsAuthenticated would allow you to modify your response appropriately.

What you do then is up to you:

  1. Display a message to the user in the pop-up requesting that they log in again.
  2. Handle the response and perform a redirect as per Pekka's recommendation.
Community
  • 1
  • 1
Zhaph - Ben Duguid
  • 26,785
  • 5
  • 80
  • 117
1

If the server has redirected you to a different login page, then you could check for the response headers (assuming they're being set) in your ajax callback, and see if the http status code is 3xx. If it is, do a manual redirect.

The $.get call returns an XMLHTTPRequest object and the property to check in that object is status, or make use of the low-level $.ajax instead of $.get.

Checkout this question for more approaches. Can't you change the response headers/status code when sending back the PartialView?

Community
  • 1
  • 1
Anurag
  • 140,337
  • 36
  • 221
  • 257
0

I might recommend an approach similar to what is described here: http://developer.fellowshipone.com/patterns/#_logout_counter

Basically, inform the user their session is going to expire via a countdown. As soon as the session expires immediately redirect to the login page.

sestocker
  • 3,522
  • 6
  • 27
  • 32