CORS headers missing when deployed on Azure Web App / Azure API

﹥>﹥吖頭↗ 提交于 2019-11-30 14:15:38
Maxime Rossini

Actually, Azure website is supposed to manage CORS for you. I think you missed a handy Azure website blade:

If our own understanding is correct, the problem with this Azure middleware is that is allows you to configure nothing but allowed origins. It lacks an "allowed headers" manageable configuration, per-URL rules, and other useful CORS HTTP headers. Worse: it drops all CORS related headers from every single HTTP response it processes, before setting its own, so it doesn't even let you handle what it doesn't.

The good thing is that you can completely disable this middleware and manage CORS by your own means, you juste have to remove every single allowed origin (including *) from the CORS settings blade in the portal. Then you can use web.config or Web Api to handle it more specifically. See the documentation:

Don't try to use both Web API CORS and App Service CORS in one API app. App Service CORS will take precedence and Web API CORS will have no effect. For example, if you enable one origin domain in App Service, and enable all origin domains in your Web API code, your Azure API app will only accept calls from the domain you specified in Azure.

See also this related issue:

So the final answer is: If your application does not need a very specific CORS management, you can use Azure App Service CORS. Otherwise you will need to handle it yourself and disable all CORS configuration in the web app.

In the end I went with easier way - removed all code-handling of CORS and simply put the headers in the web.config:

<configuration>
 <system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="http://my-client-website.azurewebsites.net" />
      <add name="Access-Control-Allow-Methods" value="*" />
      <add name="Access-Control-Allow-Headers" value="accept, content-type, x-my-custom-header" />
      <add name="Access-Control-Allow-Credentials" value="true" />
    </customHeaders>
  </httpProtocol>
 ...

(note that allow-origin doesn't have a slash at the end of the url!)

The allow-credentials part was to satisfy the SignalR, probably it could do without it.

If someone finds a reason as to why the coded way isn't working I'd like to know!

I've run into this issue, too. I think I've finally got programmatic WebAPI's CORS working in an Azure App Service with this magic combination of handler changes:

  <remove name="OPTIONSVerbHandler" />
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,POST,PUT,DELETE,HEAD,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

You do have to remove the OPTIONSVerbHandler to get rid of the default preflight responses--by using custom headers in the web.config, you just found another way to ensure those headers get written to those OPTIONS requests that never reach your app.

The key is making sure that something else is in charge of OPTIONS requests, and I believe that's achieved by re-adding the ExtensionlessUrlHandler specifying OPTIONS in the verb list. I'm not well versed in IIS, so I'm speculating about the mechanism, but it does seem to work. FWIW, this is with me spinning up WebAPI's CORS functionality in App_Start/WebApiConfig.cs like so:

config.EnableCors(new MyCorsPolicyProvider());

Where MyCorsPolicyProvider is a class that implements ICorsPolicyProvider.

I set this on azure portal, but chrome preflight still fails for cross domain request. In azure document, the preflight uses OPTION http verb, I guess chrome may just use a GET, so there is no header value for that.

My problem was that I accidentally put http instead of https into Azure AD B2C custom page config blade ... After change to https it works like a charm.

try this command on AZURE cloud shell

Azure cloud shell

az resource update --name web --resource-group ***1*** --namespace Microsoft.Web --resource-type config --parent sites/***2*** --set properties.cors.allowedOrigins="['http://localhost:5000']" --api-version 2015-06-01

****1**** = Your resource group name

****2**** = Your App name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!