I have create an Azure API Management Service and connected my APIs. I added CORS
policies to them.
I checked the Calculate effective policy and the result is this policy
<policies> <inbound> <!-- base: Begin Product scope --> <!-- base: Begin Global scope --> <cors allow-credentials="true"> <allowed-origins> <origin> https://developer.mydomain.com</origin> </allowed-origins> <allowed-methods preflight-result-max-age="300"> <method>*</method> </allowed-methods> <allowed-headers> <header>*</header> </allowed-headers> <expose-headers> <header>*</header> </expose-headers> </cors> <!-- base: End Global scope --> <!-- base: End Product scope --> <cors> <allowed-origins> <origin>*</origin> </allowed-origins> <allowed-methods> <method>GET</method> <method>POST</method> </allowed-methods> </cors> </inbound> <backend> <!-- base: Begin Product scope --> <!-- base: Begin Global scope --> <forward-request /> <!-- base: End Global scope --> <!-- base: End Product scope --> </backend> <outbound /> <on-error /> </policies>
If I call the API with C#, it is working. Then, I created a simple JavaScript to call the API but there is no way to avoid CORS
. I tried different JavaScript
<html> <head> <script src="""https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> </head> <body> <script> var url = ''; var headerKey = 'subscription-Key'; var headerValue = 'e1e21'; $.ajax({ url: url, beforeSend: function(xhrObj){ // Request headers xhrObj.setRequestHeader("Origin","https://www.puresourcecode.com/"); xhrObj.setRequestHeader("Access-Control-Allow-Origin","https://www.puresourcecode.com/"); xhrObj.setRequestHeader("Access-Control-Request-Method","GET"); xhrObj.setRequestHeader("Access-Control-Allow-Credentials","true"); xhrObj.setRequestHeader("Access-Control-Request-Headers","X-Custom-Header"); xhrObj.setRequestHeader("Access-Control-Allow-Headers","Origin, Content-Type, Accept, Authorization, X-Request-With"); xhrObj.setRequestHeader(headerKey,headerValue); }, type: "GET", contentType: "application/json; charset=utf-8", }) .done(function(data) { alert("success"); }) .fail(function() { alert("error"); }); // jQuery preflight request $.ajax({ type: "GET", headers: {headerKey: headerValue}, url: url }).done(function (data) { console.log(data); }); // XMLHttpRequest preflight request var xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.setRequestHeader(headerKey, headerValue); xhr.onload = function () { console.log(xhr.responseText); }; xhr.send(); // Fetch preflight request var myHeaders = new Headers(); myHeaders.append(headerKey, headerValue); fetch(url, { headers: myHeaders }).then(function (response) { return response.json(); }).then(function (json) { console.log(json); }); </script> </body> </html>
All of them are failing because ofCORS
. I tried to addpreflight-result-max-age="300"
and also specified theallowed-headers
like the one I use to pass the subscription key without success. I also tried to copy this file in my server with the same error.
As origin
I set *
because I thought in this way every request for every URL is accepted but obviously not.
What is the correct settings to apply in the Azure API Management to avoid CORS
?
I think to issue happens when you enable the Developer portal
. Then, in the configuration for the portal, you enable CORS
. At this point, Azure automatically adds a global policy to the API Management Service
but you don't know that.
<policies>
<inbound>
<!-- base: Begin Global scope -->
<cors allow-credentials="true">
<allowed-origins>
<origin> https://developer.mydomain.com</origin>
</allowed-origins>
<allowed-methods preflight-result-max-age="300">
<method>*</method>
</allowed-methods>
<allowed-headers>
<header>*</header>
</allowed-headers>
<expose-headers>
<header>*</header>
</expose-headers>
</cors>
<!-- base: End Global scope -->
</inbound>
</policies>
Happily, you configure CORS
in your API and when you try to call them from JavaScript, you are facing the CORS
error.
If you open the CORS
configuration in the Azure portal you can see something like that:
<policies>
<inbound>
<base />
<cors>
<allowed-origins>
<origin>*</origin>
</allowed-origins>
<allowed-methods preflight-result-max-age="300">
<method>GET</method>
<method>POST</method>
</allowed-methods>
<allowed-headers>
<header>*</header>
<header />
</allowed-headers>
<expose-headers>
<header>*</header>
</expose-headers>
</cors>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
My understanding is the portal combine the base configuration with yours. So, like in Active Directory
the more restricted policy is applying. That means in my example, only the Developer Portal
can call the APIs without CORS
issue.
Solution
Delete <base />
under <inbound>
and save.