Search code examples
javascriptasp.netajaxwindows-authentication

Firefox turning one ajax call into three http-requests, how to avoid the two calls without proper windows authorization


I managed to create an ajax call in an ASP page, but using Fiddler I see that there are actually always 3 calls, with progressively more authentication, wasting network transmission time and bandwith.

The first call has no Authorization header, and the server responds with a 6 kilobyte page saying HTTP 401.2 Unauthorized, with user friendly info about Most Likely Causes, and Things You Can Try.

Then a second request is sent, with an extra header like:

Authorization: NTLM ....(56 bytes base64)...

Now the server responds with a simple 341 byte html message just saying:

Not Authorized
HTTP Error 401. The requested resource requires user authentication.

Then a third request is sent, with a much longer Auth header like:

Authorization: NTLM ....(688 bytes base64)...

Now the response is from the code-behind, with my own 14-byte JSON message.

To me it seems wasteful to have those first two message exchanges. How do I get the ajax call to always send the full authorization header to avoid the first two responses of about 6500 bytes, and to only get my own 14 bytes of useful response?

I tried to add the xhrFields.withCredentials = true setting, but the above behaviour is seen with and without this setting.

This is the ajax call:

        $.ajax({
            type: "POST",
            url: "Timeout_Test.aspx/GetAjax",
            data: JSON.stringify(data),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            xhrFields: {
                withCredentials: true
            },
            success: function (data, textStatus, jqXHR) {...},
            error: function (jqXHR, textStatus, errorThrown) {...}
        });

The same happens with a javascript asp call for my experimentation with trying to avoid session timeout:

    function get_asp() {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function () {...}
        xmlHttp.withCredentials = true;
        xmlHttp.open("GET", "Timeout_Test.aspx?type=keepalive", true); // true for asynchronous 
        xmlHttp.send(null);
    }

The web.config contains:

<authentication mode="Windows"/>

and to access the page I must enter the windows login name and my password, once. The page contains a button and some javascript logic with an interval timer, and every minute or so an ajax call is done. It actually beats me how the javascript knows the login credentials, but the ajax call works really nice. The two intermediate 401 error messages are hidden from the javascript code and not shown anywhere, except visible in the Fiddler http snooping tool.

The firebug debug session only shows one successful ajax call, while Fiddler clearly shows 3 http requests and 2 error responses with 401. I make time stamped output on my page, and am very sure I only do ONE ajax call every minute. The 3 responses are rapid, in a total of about 1 second.

No, make that total of 35 milliseconds. Request 1 at T.471, response 1 at T.473, then Req2 at T.487, Resp2 at T.489, finally Req3 at T.502 with Resp3 at T.505, where T is time of 18:22:12. According to Fiddler Statistics pane.

With the Visual Studio 2015 C# debugger I found that for each ajax call, the code behind is only called once. Hence, the first two requests with the 401 error responses, did not reach the code-behind, only the web server.

I must guess that the Firefox browser, that is interpreting and running the javascript code with the ajax call, is doing the three http requests with progressively more authorization "automatically".

The question is: how do I program the ajax call so that Firefox only does the third version of the http-request, without going through the first two unsuccessful http-requests?


Solution

  • OK this weird behaviour seems to come from the interaction between TWO requests issued "at the same time". I already showed code for an ajax call and for an asp call. This is a test page to see if and how a session times out with ajax and/or asp calls. When those two are close together, the triple http-request is seen.

    In more normal cases that we have either an ajax call, OR an asp call, there is only one http request, entirely without authorization header.

    As in such cases the first http-request succeeds, this seems an issue with the web server, i.e. IIS, rather than the browser (Firefox). On the other hand, as Firefox can recover from the 401 by sending an extra header, this may be a standard http protocol, rather than a "bug".

    I can live with this situation, as in normal operation I can avoid making both calls at the same time.