CORS Preflight request not working with Azure API Management
Asked Answered
C

4

6

I have 2 Azure Websites (ASP.NET MVC 5 and ASP.NET WebApi 2). The MVC website has some jQuery which tries to post CORS request to the WebApi. It works just fine if it connects directly to the WebApi. However it doesn't work when trying to connect through the API Management.

The error I got in Chrome is:

XMLHttpRequest cannot load https://XXXXXX.azure-api.net/api/search. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://YYYYYY.azurewebsites.net' is therefore not allowed access.

I ruled out the problem being with the WebApi config, because as I said it works directly.

Below is my policy:

<policies>
    <inbound>
        <cors>
            <allowed-origins>
                <origin>*</origin>
                <!-- allow any -->
            </allowed-origins>
            <allowed-headers>
                <header>accept</header>
                <header>accept-encoding</header>
                <header>access-control-request-headers</header>
                <header>access-control-request-method</header>
                <header>connection</header>
                <header>content-type</header>
                <header>host</header>
                <header>origin</header>
                <header>referer</header>
                <header>user-agent</header>
            </allowed-headers>
            <expose-headers>
                <header>access-control-allow-headers</header>
                <header>access-control-allow-origin</header>
                <header>cache-control</header>
                <header>content-length</header>
                <header>date</header>
                <header>expires</header>
                <header>pragma</header>
                <header>server</header>
                <header>set-cookie</header>
                <header>x-aspnet-version</header>
                <header>x-powered-by</header>
            </expose-headers>
        </cors>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
</policies>

Any ideas?

Classic answered 15/11, 2015 at 12:28 Comment(7)
There is a typo in your allowed-headers/access-control-request-headersn Some people have experienced issues getting CORS working with mistyped headers #26122324 Is that just a typo in the SO question, or in your original policy?Longo
Cheers, I fixed the type on the policy but didn't make any difference. :(Classic
Are you also adding an Authorization header? I get this error using api apps with CORs.Fictionalize
Any luck with this? I'm currently dealing with this issue myself, and haven't found much helpful on the web.Crabbe
Same here. I have been struggling for a week and try everything I can search for on web. Now I totally get what CORS for and still I get 'No 'Access-Control-Allow-Origin' header is present' error with my angular localhost app. Very frustrating.Correlation
@Darrel Miller: What typo?Aiguille
@Aiguille The original question had access-control-request-headersn. It was fixed in the questionLongo
S
4

After spending many weeks fighting this issue, and coming up empty, I (with the help of Microsoft Support) discovered a bug in Azure API Management. If you have multiple APIs and one of them does not have an URL suffix (even if it's not the one that's failing), check it's CORS policy. The first API we put in Azure API Management didn't have any methods other than GET, so we set a CORS policy to only allow GET and OPTION. However, the bug that exists seems to make all inbound pre-flight requests route to the API without an URL suffix. So I was able to fix my issue by added a PUT (and POST for good measure) to the CORS policy of an unrelated API.

TL;DR: Check to make sure the CORS policy of the API with no URL suffix allows the method that's failing.

Hope this saves someone's sanity.

Superficies answered 2/3, 2022 at 21:15 Comment(2)
Idk if this is your problem, but I had to go to Developer Portal section > Portal Overview and then enable CORS for all API's (and make sure you delete cors configuration on any lower levels so that you just inherit the All API's setting.)Frankly
From all my heart, thank you.Jupiter
A
2

CORS policy intended use is for the cases when your backend does not support CORS. In that case you can put this policy in and it will reply to OPTION requests without forwarding them to your backend. And you can use this policy to decide which origins/headers/methods to process for CORS.

Alternatively, if your backend already supports CORS and you see no benefit in handling CORS flow on APIM level you could just proxy the entire flow. For that to happen you should remove CORS policy and create a new operation in your API in APIM with OPTIONS method, so that OPTIONS requests would be forwarded to backend normally.

Aphotic answered 22/1, 2016 at 20:10 Comment(3)
Really??? CORS with APIM is so confusing. Is there somewhere that explains how to do this? I've been searching for a while but have not find instructions that make sense to me. I feel stupid.Aiguille
CORS in general is not really a clear spec. The best place to start that I can suggest is MDN: developer.mozilla.org/en-US/docs/Web/HTTP/CORS. After that article it should be clearer why cors policy was added into APIM and what problems it solve.Aphotic
Sorry, I was referring to setting up APIM to forward CORS requests to the backend. I get CORS in general, but I'm struggling with CORS setup in APIM. And, I understand how APIM can handle CORS negotiation via policy setup, but not how it do so by forwarding to the backend. This answer tells me how to do this in general steps, but not with enough detail for me to follow.Aiguille
N
2

For me, the issue was that there was a global APIM policy that was taking precedence over the policy configured at the API level. My API had an open CORS policy, but the APIM instance had a global policy that limited access to specific domains.

You can access the global settings by clicking where it says "All APIs" and then edit the CORS policy from there:

APIM screenshot

Nixie answered 14/2 at 4:53 Comment(1)
Spent a lot of time before I found this setting, and things were sorted in two minutes. Thank you!Lamkin
M
0

I was getting below preflight error from APIM and found that issue is that my policy <method>*</method> is actually not working. Changing the policy to explicitly add all the HTTP Verbs like below has resolved my issue.

<allowed-methods preflight-result-max-age="300">
            <method>OPTIONS</method>
            <method>GET</method>
            <method>POST</method>
            <method>PUT</method>
            <method>PATCH</method>
            <method>DELETE</method>
        </allowed-methods>

enter image description here

Mensuration answered 11/6, 2022 at 5:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.