1 Reply Latest reply on Dec 15, 2015 2:38 PM by Martin Seifert

    WDC: Basic HTTP authentication in jQuery AJAX call with JSON-P

    Martin Seifert

      Hi all!

       

      I'm working on a Web Data Connector to a REST API which requires basic HTTP authentication (just like web data connector authentication ).

       

      I want to bypass the basic auth of it in my jQuery AJAX call (with JSON-P) by modifying the request header and found multiple options to do so (e.g. http://stackoverflow.com/questions/5507234/how-to-use-basic-auth-and-jquery-and-ajax ). The reason for this is: I don't want to see the nasty popup that results when the server sends a 401 error (missing authentication). When this popup appears and I enter my credentials there again (after I already entered them in a form in my WDC from where they get stored in tableau.username and tableau.password), they get stored for the session (request headers are modified properly) and I can send as many requests to the server as I want without any additional popups. But I don't want the popup in the first place... I tried all sorts of setups in various combinations, nothing worked, the request header is not modified at all before entering my credentials in the popup.

       

      Here is some code without previously set variables (tableau.username and tableau.password contain the correct credentials) and all the usual stuff:

       

      var xhr = $.ajax({

              url: connectionUri,

              dataType: 'jsonp',

              beforeSend: function (xhr) {

                xhr.setRequestHeader('Authorization', 'Basic ' + btoa(tableau.username + ":" + tableau.password));

              },

      /*

      // Unused alternative Basic HTTP Auth Options for AJAX (?)

      headers: {

        'Authorization': 'Basic ' + btoa(tableau.username + ':' + tableau.password)

      },

       

      xhrFields: {

        withCredentials: true

      },

       

      username: tableau.username,

      password: tableau.password,

      */

              success: function (data) {

                // MAGIC STUFF HERE

                tableau.dataCallback(dataToReturn, lastRecordToken, hasMoreData);

                }

                else {

                  tableau.abortWithError("No results found.");

                }

              },

              error: function (xhr, ajaxOptions, thrownError) {

                // If the connection fails, log the error and return an empty set.

                tableau.log("Connection error: " + xhr.responseText + "\n" + thrownError);

                tableau.abortWithError("Error while trying to connect.");

              }

            });

       

       

       

      Here are the headers before I enter my credentials in the popup:

       

      Request Headers:

      Host: WHATEVER

      User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0

      Accept: */*

      Accept-Language: en-US,en;q=0.5

      Accept-Encoding: gzip, deflate

      Referer: http://localhost:8888/myConnector.html

      Connection: keep-alive

       

      Response Headers:

      HTTP/1.1 401 Unauthorized

      Cache-Control: private

      Content-Type: text/html

      Server: Microsoft-IIS/7.5

      X-AspNet-Version: 4.0.30319

      WWW-Authenticate: Basic realm="magicRealmSetByTheServer"

      X-Powered-By: ASP.NET

      Date: Mon, 14 Dec 2015 16:58:10 GMT

      Content-Length: 1293

       

       

       

      And after I entered my credentials in the popup:

       

      Request Headers

      Host: WHATEVER

      User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0

      Accept: */*

      Accept-Language: en-US,en;q=0.5

      Accept-Encoding: gzip, deflate

      Referer: http://localhost:8888/myConnector.html

      Authorization: Basic cG9zdFxmdW5uZWxjb2NrcGl0LnRhYmxlYXU6dTRtdlEyTldZMFduUV9YM1N5T0Y=

      Connection: keep-alive

       

      Response Headers:

      HTTP/1.1 200 OK

      Cache-Control: private

      Content-Length: 97921

      Content-Type: application/json; charset=utf-8

      Server: Microsoft-IIS/7.5

      Response-Time: 526

      X-AspNet-Version: 4.0.30319

      X-Powered-By: ASP.NET

      Date: Mon, 14 Dec 2015 17:02:56 GMT

       

       

       

      So we see, after re-entering my credentials, the Request Header contains what I was trying to set with the code snipped highlighted. Why is my beforeSend option incorrect? Do I have to deal with the realm specifically somehow?

       

      Any idea on how to modify the request headers in the first place? What is missing in my configuration? Or any suggestion on alternative techiques (I tried CORS, too, but the server rejected my call and since I don't have access to it, it's unlikely this will change)?

       

      Best regards and thanks in advance

      Martin

        • 1. Re: WDC: Basic HTTP authentication in jQuery AJAX call with JSON-P
          Martin Seifert

          Hello Forum

           

          I actually found the answer: There is no way to avoid this nasty popup for basic authentication with an ajax JSON-P call and it's unlikely this ever will change:

           

          Basic Authentication does not work with JSONP · Issue #1781 · jquery/jquery · GitHub

           

          The solution for this is unfortunately not like a piece of cake... The alternative to a JSON-P ajax is using a CORS proxy that is registered (kind of "whitelisted") with the API provider.

           

          Since CORS is not the newest invention it might very well be your API already has one, you just need to find it. I was fortunate enough to get one after asking kindly (actually, they already had one and simply told me where)

           

          After finding the server you simply need to modify the URL for the ajax call a bit and use the dataType option "json" instead of "jsonp".

           

          If you stumble upon this issue, too, I'm happy to help where I can, but I have to say (if you didn't guess it already) I'm not a JS coder...

           

          Thanks everyone who gave a thought into this!