Access to azure hosted API App denied by CORS policy
<p>We are a team working on azure web services. What we want to achieve is having a JavaScript frontend which can communicate with our Java API App hosted in Azure. </p>

<p>We are using Active Directory for Authentication. And we have configured CORS within the Azure portal.</p>

<p>We have created a Java backend with Swagger Editor as it is described in <a href="https://azure.microsoft.com/en-us/documentation/articles/app-service-api-java-api-app/" rel="nofollow noreferrer">this article</a>. We have just advanced this example to support our own data model. So also the <code>ApiOriginFilter</code> class is still unchanged:</p>

<pre><code>@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaJerseyServerCodegen", date = "2016-11-08T15:40:34.550Z")
public class ApiOriginFilter implements javax.servlet.Filter {
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        res.addHeader("Access-Control-Allow-Origin", "*");
        res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
        res.addHeader("Access-Control-Allow-Headers", "Content-Type");
        chain.doFilter(request, response);

    }

    public void destroy() {}

    public void init(FilterConfig filterConfig) throws ServletException {}
}
</code></pre>

<p>Our frontend runs on a local PC. So furthermore, we added our origin "<a href="http://localhost:8888" rel="nofollow noreferrer">http://localhost:8888</a>" in the CORS in the azure portal.</p>

<p>The frontend JavaScript code looks like this:</p>

<pre><code>var app = angular.module('demo', ['AdalAngular', 'ngRoute'])
    .controller('GetDataController', ['$scope', '$http', '$timeout', 'adalAuthenticationService', function($scope, $http, $timeout, adalAuthenticationService) {
        $scope.loggedIn = "Logged out";
        $scope.responseData = "No Data";
        $scope.loading = "";

        $scope.loginAdal = function(){
          adalAuthenticationService.login();
        }

        $scope.getData = function(){            
          $http.defaults.useXDomain = true;
          delete $http.defaults.headers.common['X-Requested-With'];

          $scope.loading = "loading...";
          var erg = $http.get('http://&lt;our-backend&gt;.azurewebsites.net/api/contacts')
            .success(function (data, status, headers, config) {
                console.log("SUCCESS");
                $scope.loading = "Succeeded";
                $scope.loggedIn = "LOGGED IN";
                $scope.responseData = data;     
            })
            .error(function (data, status, header, config) {
                console.log("ERROR");
                $scope.loading = "Error";
                console.log("data: ", data);
            });
        }
    }]);

    app.config(['$locationProvider', 'adalAuthenticationServiceProvider', '$httpProvider', '$routeProvider', function($locationProvider, adalAuthenticationServiceProvider, $httpProvider, $routeProvider) {

        $locationProvider.html5Mode({
          enabled: true,
          requireBase: false,
          hashPrefix: '!'
        });

        var theEndpoints = {
          "https://&lt;our-backend&gt;.azurewebsites.net/api/contacts": "f0f91e4a-ad53-4a4a-ac91-431dd152f386", 
        };

        adalAuthenticationServiceProvider.init(
        {
            anonymousEndpoints: [],
            instance: 'https://login.microsoftonline.com/',
            tenant: "&lt;our-tenant&gt;.onmicrosoft.com", 
            clientId: "f6a7ea99-f13b-4673-90b8-ef0c5de9822f", 
            endpoints: theEndpoints 
        },
        $httpProvider 
        );
}]);
</code></pre>

<p>But calling the backend from the frontend we get the following error after logging in into our tenant:</p>

<blockquote>
  <p>XMLHttpRequest cannot load <a href="https://[our-backend].azurewebsites.net/api/contacts" rel="nofollow noreferrer">https://[our-backend].azurewebsites.net/api/contacts</a>. Redirect from '<a href="https://[our-backend].azurewebsites.net/api/contacts" rel="nofollow noreferrer">https://[our-backend].azurewebsites.net/api/contacts</a>' to 
  '<a href="https://login.windows.net/12141bed-36f0-4fc6-b70c-" rel="nofollow noreferrer">https://login.windows.net/12141bed-36f0-4fc6-b70c-</a>
  43483f616eb7/oauth2/autho…
  %2Fapi%2Fcontacts%23&amp;nonce=7658b7c8155b4b278f2f1447d4b77e47_20161115124144'
  has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
  header  is present on the requested resource. Origin 'null' is
  therefore not  allowed access.</p>
</blockquote>

<p>In Chrome's developer console we see four requests to our contacts api. But all have the status code "302 Redirect". The first two entries contain the header "Access-Control-Allow-Origin:<a href="http://localhost:8888" rel="nofollow noreferrer">http://localhost:8888</a>" but the other two entries do <em>not</em> contain this header. </p>

<p>EDIT: One of the first two entries is an XmlHttpRequest and one of the second entries is the same XmlHttpRequest but with <em>https</em> instead of <em>http</em>.</p>

<p>Based on this, we created a new filter in our backend to set the access-control-allow-origin field:</p>

<pre><code>@Provider
public class CrossOriginFilter implements ContainerResponseFilter {
    @Override
    public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) throws IOException {
        containerResponseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
        containerResponseContext.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
        containerResponseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
        containerResponseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
        containerResponseContext.getHeaders().add("Access-Control-Max-Age", "1209600");    
    }
}
</code></pre>

<p>and deleted these three fields from ApiOriginFilter:</p>

<pre><code>res.addHeader("Access-Control-Allow-Origin", "*");
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
res.addHeader("Access-Control-Allow-Headers", "Content-Type");
</code></pre>

<p>Now if we run the <em>backend</em> locally, we see all these headers from the 2nd filter in Chrome's developer console. </p>

<p>But as soon as we deploy the backend to azure we loose this headers somehow and again have the same error when accessing the api from the frontend:</p>

<blockquote>
  <p>XMLHttpRequest cannot load <a href="https://[our-backend].azurewebsites.net/api/contacts" rel="nofollow noreferrer">https://[our-backend].azurewebsites.net/api/contacts</a>. Redirect from '<a href="https://[our-backend].azurewebsites.net/api/contacts" rel="nofollow noreferrer">https://[our-backend].azurewebsites.net/api/contacts</a>' to 
  '<a href="https://login.windows.net/12141bed-36f0-4fc6-b70c-" rel="nofollow noreferrer">https://login.windows.net/12141bed-36f0-4fc6-b70c-</a>
  43483f616eb7/oauth2/autho…
  %2Fapi%2Fcontacts%23&amp;nonce=7658b7c8155b4b278f2f1447d4b77e47_20161115124144'
  has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
  header  is present on the requested resource. Origin 'null' is
  therefore not  allowed access.</p>
</blockquote>

<p>EDIT: As I wrote there are two XmlHttpRequests made. And the second one is <em>https</em>. So If in the line</p>

<pre><code>var erg = $http.get('http://&lt;our.backend&gt;.azurewebsites.net/api/contacts')
</code></pre>

<p>I change <em>http</em> to <em>https</em> we run into the <code>error()</code> callback function. And in the console we have the output:</p>

<blockquote>
  <p>data:  User login is required</p>
</blockquote>

<p>But as I wrote before. We are already logged in to our tenant. So what is going wrong?</p>