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?

Adam Szabo
  • 11,302
  • 18
  • 64
  • 100
  • There is a typo in your allowed-headers/access-control-request-headersn Some people have experienced issues getting CORS working with mistyped headers http://stackoverflow.com/questions/26121824/azure-api-management-cors-and-post?rq=1 Is that just a typo in the SO question, or in your original policy? – Darrel Miller Nov 16 '15 at 03:55
  • 1
    Cheers, I fixed the type on the policy but didn't make any difference. :( – Adam Szabo Nov 16 '15 at 19:36
  • Are you also adding an Authorization header? I get this error using api apps with CORs. – ozkary Jan 05 '16 at 04:45
  • 2
    Any luck with this? I'm currently dealing with this issue myself, and haven't found much helpful on the web. – Steve Eggering Apr 20 '20 at 19:24
  • 1
    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. – RocketsLee May 06 '20 at 06:18
  • @Darrel Miller: What typo? – steve Jan 12 '21 at 17:28
  • @steve The original question had `access-control-request-headersn`. It was fixed in the question – Darrel Miller Jan 13 '21 at 01:03

3 Answers3

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.

Vitaliy Kurokhtin
  • 7,205
  • 1
  • 19
  • 18
  • 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. – steve Jan 12 '21 at 17:26
  • CORS in general is not really a clear spec. The best place to start that I can suggest is MDN: https://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. – Vitaliy Kurokhtin Jan 12 '21 at 22:24
  • 1
    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. – steve Jan 14 '21 at 14:47
0

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.

  • 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.) – The Muffin Man May 25 '22 at 16:26
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

ISP
  • 53
  • 1
  • 7