3

I am getting following error for a jQuery call to my azure app proxy

XMLHttpRequest cannot load https://azentsearchdev01-mytenant.msappproxy.net/search?text=mytext&type=json&callback=json_callback. Response for preflight is invalid (redirect)

This is what I am doing

  1. From mytenantsite.sharepoint.com, making a call jQuery call to an Azure app on the folliwing url - https://azentsearchdev01-mytenant.msappproxy.net

  2. As part of the call, I am setting an authorization header with authentication token (access token) from Azure AD

  3. The jQuery call is fails with a 302 redirect to https://login.microsoftonline.com/

Here is my code

//authorization context
var resource = 'https://azentsearchdev01-mytenant.msappproxy.net/';
var endpoint = 'https://azentsearchdev01-mytenant.msappproxy.net/search?text=mytext&type=json&callback=json_callback';
   
var authContext = new AuthenticationContext({
        instance: 'https://login.microsoftonline.com/',
        tenant: 'mytenant.onmicrosoft.com',
        clientId: 'guid for client id',
        postLogoutRedirectUri: window.location.origin,
        cacheLocation: 'localStorage'
    });

//save tokens if this is a return from AAD
authContext.handleWindowCallback();

var user = authContext.getCachedUser();
if (user) {  //successfully logged in
    authContext.acquireToken("https://graph.windows.net", function (error, token) {
      if (error || !token) {
         jQuery("#loginMessage").text('ADAL Error Occurred: ' + error);
             return;
      }

      $.ajax({
        type: 'GET',
     url: endpoint,
  headers: {
           Accept: 'application/json',
           },
    beforeSend: function(xhr, settings) { 
   xhr.setRequestHeader('Authorization','Bearer ' + token); 
     }
        }).done(function (data) {
                jQuery("#loginMessage").text('success');
               }).fail(function (err) {
                jQuery("#loginMessage").text('Error calling endpoint: ' + err.statusText); **-->This is where the code lands**
               }); 

So far -

Based on what I have read, this is known gap in current state of how browsers handle a CORS preflight redirects. Reference link.

Question -

Are there any options to make a successful call to an app that requires cors preflight redirect?

Nitin Rastogi
  • 1,446
  • 16
  • 30
  • 1
    Can do all this through a server side proxy that you control – charlietfl May 13 '17 at 17:26
  • That would be worst case option. Is client side not an option at all? – Nitin Rastogi May 13 '17 at 17:51
  • Not based on current cors implementation in browsers – charlietfl May 13 '17 at 18:27
  • 1
    I think your problem is a different issue than the one at https://stackoverflow.com/questions/34949492/cors-request-with-preflight-and-redirect-disallowed-workarounds/39728229#39728229. The spec change & Chrome 57 change was for if the server responds with with 200 or 204 to a preflight OPTIONS & then responds to a following GET with a 30x, then Chrome 57+ will now follow the redirect rather than erroring. But in your case the server responds to the OPTIONS request itself with a 302. Per the spec, a 302 response to the OPTIONS request itself isn’t acceptable for a preflight. Hence the error. – sideshowbarker May 13 '17 at 23:02
  • The only option here that would enable a cross-origin request from frontend JavaScript to work in this case is for the server behavior to be changed such that it doesn’t respond with a 302 redirect to a preflight OPTIONS request. A 302 response to the OPTIONS request itself is never an acceptable response to a preflight—not in any version of any browser nor per the CORS (Fetch) spec. – sideshowbarker May 13 '17 at 23:09
  • Very interesting. Considering the response came from login service of Microsoft's cloud platform, I don't have much control over it. Looks like I will have to put in an intermediate server side layer to handle this, as suggested by charlietfl. – Nitin Rastogi May 14 '17 at 00:46
  • 1
    Based on the code, you were acquiring the token for the resource `https://graph.windows.net`. And the redirection response seems the access token doesn't work for the server. How you protect the server and can you check it from other client like Fiddler? – Fei Xue May 15 '17 at 02:15
  • @NitinRastogi Have you fixed this issue now? If not, please feel free to let me know. – Fei Xue May 18 '17 at 05:29
  • The issue is partly resolved. I am able to get the token to my app by replacing the "https://graph.windows.net" with the client id of my app. However, the pre-flight issue persists. The ajax request to my App includes an authorization header. This in turn results in Options Requests and Chrome doesn't pass the authorization header causing the issue. This works fine in IE as it passes the authorization header. I believe I would be required to work on IIS settings for the site in order to allow Options without authentication. – Nitin Rastogi May 18 '17 at 13:09
  • @FeiXue-MSFT - Found exactly same issue as mine. Solution 2 documented here - http://www.azurefieldnotes.com/2016/12/02/claims-to-windows-identity-translation-solutions-and-its-flaws-when-using-azure-ad-application-proxy/. CORS configuration is not yet available in App proxy. What options do I have?. – Nitin Rastogi May 18 '17 at 17:51
  • A normal way to overcome the CORS issue is using build a proxy the Azure AD App proxy. You can send the cross domain request to your proxy instead of Azure AD app proxy and your proxy forward the request to Azure AD app proxy. Also you may submit feedback from [here](https://feedback.azure.com/forums/34192--general-feedback) if you want to Azure AD app proxy to enable the CORS feature. – Fei Xue May 19 '17 at 05:28
  • Thanks @FeiXue-MSFT. I will work on an intermediate proxy and have submitted the feedback - https://feedback.azure.com/forums/34192--general-feedback/suggestions/19335826-cors-for-app-proxy – Nitin Rastogi May 19 '17 at 14:50

1 Answers1

2

To overcome the CORS issue for the Azure AD app proxy, we can develop a proxy for the Azure AD App proxy.

And if anyone want to Azure AD app proxy to support CORS, you can vote it through this link.

Fei Xue
  • 14,369
  • 1
  • 19
  • 27
  • So, I now created an intermediate API project deployed as an App Service and have set the CORS policy. However, when making call to the api endpoint, I am getting following error - "XMLHttpRequest cannot load http://myapi.azurewebsites.net/api/search/. Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'". So the question is, where do I set the custom headers?. I have my API hosted as a asp.net core project. – Nitin Rastogi Aug 18 '17 at 14:45
  • I think I found the approach here - https://learn.microsoft.com/en-us/aspnet/core/security/cors – Nitin Rastogi Aug 18 '17 at 15:03