0
votes

I have a .NET Core API hosted on Azure (azure app service) and it is running behind APIM. I now need to call this API from a front-end (again using the APIM endpoint) and I have been unable to set up CORS properly. I do not want to define CORS in code - my .NET code has zero CORS policy setup.

CORS is set up at the app service level by adding the allowed origins in the CORS blade but the preflight request still comes without CORS header when calling the API through APIM (thus I get "Response to preflight request doesn't pass access control check..."). I have added a CORS policy to the APIM instance for All Operations for the respective API but it still does not work. The "Options" request comes back without the Access-Control-Allow-Origin header on the browser debugger. If I skip APIM and call the API directly, it works fine. Am I missing something obvious here?

cors policy in app service CORS Policy in APIM:

<policies>
    <inbound>
        <base />
        <cors>
            <allowed-origins>
                <origin>*</origin>
            </allowed-origins>
            <allowed-methods>
                <method>GET</method>
                <method>POST</method>
                <method>OPTIONS</method>
                <method>TRACE</method>
                <method>PUT</method>
                <method>DELETE</method>
                <method>HEAD</method>
                <method>PATCH</method>
            </allowed-methods>
            <allowed-headers>
                <header>*</header>
            </allowed-headers>
        </cors>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
        <set-header name="Access-Control-Allow-Origin" exists-action="override">
            <value>*</value>
        </set-header>
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

Note that I also tried to specifically add the front-end URL https://frontend.com in those settings and check Allow Credentials checkbox, which also changed nothing.

When I added the set-header option, if I directly call the API via postman then the Access-Control-Allow-Origin is returned on the postman call, but on the browser preflight request still nothing.

debugger

EDIT:

Per response.. I tried to simplify the scenario by creating a brand new API with the template "weather forecast" .net core api deployed to it. No authentication and CORS policy set to *. I proceeded to add this API to my APIM instance - simply clicked the App Service option in the APIM menu and added CORS policy - nothing else. Then, in a separate URL (for CORS to trigger) I deployed a simple HTML with a call to the new APIM endpoint. The headers look exactly the same - no CORS header and the call fails, if I skip APIM and call backend directly it works. I cannot spot any error in my set up at this point, no idea what I may be missing. Screenshots below

app service setup apim apim 2 request failure

3
Still struggling with this. I tested bypassing APIM and CORS works properly when directly calling the backend so the problem seems to be APIM itself. No matter what policies I try to set, the options request always comes back without any headers as above. I tried to forward options requests (route *) to back end but it also did not work.YuriW
Is there any progress?Jason Pan
Edited with new 'clean' testYuriW

3 Answers

1
votes

It seems you can access your api successfully, but cannot see the response header you set. The problem might be that you hide some response header in your code.

My suggestion is:

Check the response header by browse your app service url: https://yourbackend.azurewebsites.net/. If the response header just two elements like your final picture, then the Access-Control-Allow-Origin would not appear.

_____________________________________________________________________________

For testing:

I created a back-end api project and a front-end project to call the api, and publish them to separate app service.

Then, test to call the api from front-end app, it failed with this ERROR:

Access to XMLHttpRequest at 'back-end url' from origin 'front-end url' has been blocked by CORS policy:

After configuring the CORS option on portal, calling "https://myfront-end.azurewebsites.net/home/test", which worked as expected. _____________________________________________________________________________

Now, it comes to the APIM part:

  1. I created an APIM and add my back-end app service as an API: enter image description here

  2. Configure the settings to include my app service url: enter image description here

  3. Configure CORS policy with yours: enter image description here

4.Modify the API's endpoint to my front-end project: enter image description here

  1. Which works fine with the header "Access-Control-Allow-Origin" you said: enter image description here
0
votes

I am running into the same issue.

If I set the "allowed methods" in the "inbound policy" like you have and try to do a PATCH, I get the error as you do and the response header of pre-flight request does not have anything other than the two that you see.

However, if I change the "allowed methods" inbound policy to * and remove GET, POST, OPTIONS etc.., then the preflight request has all the response headers as expected: Screenshot

You should try setting "*" for allowed methods in the inbound policy.(As a side note, I do not have any "set headers" in outbound policy)

Note: I get "Method patch is not allowed by Access-Control-Allow-Methods in preflight response." even though it's present in the response header.

0
votes

I have finally found the issue. When you create an API Management instance, usually you'll also need a portal for users to view your schemas, subscribe to your API and test it in the browser. To do this, once the APIM instance is created, you just have to go to the Portal Overview section and click Publish + Enable CORS, which I did for our API. What this actually does is that it sets a CORS policy with origin=Portal URL at the "All APIs" level and this policy overwrites any CORS policy you might set at an API/method level.

Unfortunately, I never considered that there might be any policies defined at the "All APIs" level so I never even clicked there. Additionally, there is no warning on the interface that one might be there nor that it overwrites policies at a lower level. Once I set the proper origin at the "All APIs" level, everything worked perfectly. Hope this helps someone with similar issues!

enter image description here