Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there ANY way to suppress the browser's login prompt on 401 response when using XmlHttpRequest

I am using jQuert .ajax function to call a page method. The site is using FormsAuthentication. So when an authentication ticket expires a call to the page method will obviously cause a redirect to the login page.

Now, the geniuses that wrote the System.Web.Handlers.ScriptModule decided that if for some reason a REST style call to a page method or a web service method, from JavaScript causes a 302 Redirect, they're going to just simply turn the response into a 401 Unauthorized. This causes a browser to popup a login UI that is totally misleading, as the user tries to type in their username and password, which means nothing, because FormsAuthentication is used. Finally, when the user clicks Cancel, the 401 comes through to the error handler.

So, the question is, how can one disable the browser's login UI prompt in any way? Some people on the web suggest to use a username and password in the XHR request, but it does not seem to work.

like image 822
Strelok Avatar asked Dec 11 '08 23:12

Strelok


2 Answers

I think I worked around it. Ofcourse relying on internal MS AJAX related errors is not really nice, but this will do the trick for others faces with this problem.

Basically what you do, is you set the X-MicrosoftAjax header to the value Delta=true (case is important here), the ScriptModule will interpret this as a normal redirect, and turn the response into a 200, but will set the pageRedirect data string for any ScriptManager (MS-AJAX PageRequestManager) on the page to consume. The jQuery.ajax function will still see this as an error, so basically you can check for pageRedirect in responseText property of the XHR and hadle it accordingly. Like sending the user to the login page of something.

    $.ajax({
            type: "POST",
            url: postUrl + "/SomePageMethod",
            data: "{searchString:\"" + escape(searchString) + "\"}",
            contentType: "application/json; charset=utf-8",
            beforeSend: function(xhr) {
                xhr.setRequestHeader("X-MicrosoftAjax","Delta=true");
            },
            dataType: "json",
            success: onSuccess,
            error: onError
        });

function onError(xhr, e, textStatus) {
    var isAjaxRedirect = xhr.status == 200 && xhr.responseText.match(/pageRedirect/);
    if (isAjaxRedirect == "pageRedirect") {
        // forms authentication ticket expired
        location.href = "a session timeout page, or a login page or whatever";
    }
}
like image 78
Strelok Avatar answered Oct 14 '22 11:10

Strelok


This can be disabled in IIS. Details described below are for IIS6 but it shouldn't be hard to find the relevant items for IIS7 and up.

  1. Find the relevant site.
  2. Open the "Directory Security" tab, or relevant tab in your version of IIS
  3. Click "Edit" within "Authentication and access control" section
  4. Un-tick "Integrated Windows authentication"

You should no longer see the popup in your browser and be able to send back the correct status codes as you wish.

like image 21
John_ Avatar answered Oct 14 '22 10:10

John_