0

I am trying to get CORS to work with a new WebAPI project. The project is just the default WebAPI template (i.e. has MVC and WebAPI references) using ActiveDirectoryBearerAuthentication.

Whenever I try and make a request to my API I am met with the following error:

XMLHttpRequest cannot load https://localhost:44385/api/values. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://localhost:44369' is therefore not allowed access.

I have installed Microsoft.Owin.Cors, and Microsoft.AspNet.WebApi.Cors.

My WebApiConfig is this:

public static void Register(HttpConfiguration config)
{
    config.EnableCors();
    ....

My Startup.Auth is this:

public void ConfigureAuth(IAppBuilder app)
{
    app.UseCors(CorsOptions.AllowAll);

    app.UseWindowsAzureActiveDirectoryBearerAuthentication(
    ....

Solutions around the net say to add:

    <customHeaders>
        <!-- Adding the following custom HttpHeader will help prevent CORS from stopping the Request-->
        <add name="Access-Control-Allow-Origin" value="*" />
    </customHeaders>

to the web.config. However, doing this just allows everything regardless of whether Microsoft.AspNet.WebApi.Cors is installed, enabled, or not.

Mardoxx
  • 3,964
  • 5
  • 33
  • 57
  • Aren't you keen you allow everything, or you still want limited access and block some other requests – Mrinal Kamboj Sep 23 '16 at 15:43
  • one thing to know is that IE demands the inclusion of P3P header in response in order for CORS to work – pm100 Sep 23 '16 at 15:45
  • I want to block everything except one domain. I thought I'd work backwards to ensure it is working. If I hadn't have done this I would have thought that the web.config solution fixed it -- it does not it just allows everything regardless of CORS config. – Mardoxx Sep 23 '16 at 15:45

3 Answers3

1

To allow only a single domain you can do the following:

<system.webServer>
 <httpProtocol>
  <customHeaders>
    <remove name="X-Powered-By" />
    <clear />
    <add name="Access-Control-Allow-Origin" value="http://www.myalloweddomain.com" />
  </customHeaders>
 </httpProtocol>
</system.webServer>

However, that's only allowed for a single domain. If you try to add an additional add node your site won't load. If you want to allow multiple domains, then you need to try one of the solutions listed here.

Community
  • 1
  • 1
Necoras
  • 4,563
  • 1
  • 16
  • 44
  • I tried just this and it works, thanks. But then what is the point of the CORS middleware? – Mardoxx Sep 23 '16 at 16:02
  • I assume you mean the pieces you've done in code? As I said at the end of my answer, the web.config settings only work for a single domain. Code solutions allow multiple domain whitelisting. Additionally, some people just prefer having solutions in code rather than in the web.config. – Necoras Sep 23 '16 at 16:04
0

Things to check:

  • Owin kicks in on IIS (make sure you're including Microsoft.Owin.Host.SystemWeb)
  • Check that IIS doesn't hijack your request IIS hijacks CORS Preflight OPTIONS request
  • Use fiddler to fire OPTION request directly to specified url (sometimes the PREFLIGHT request just mask 500 returned by server) - browsers aren't very good in handling that
Community
  • 1
  • 1
Ondrej Svejdar
  • 19,236
  • 4
  • 49
  • 77
  • I shall have a look, thanks. The answer to that SO post says "... as a last resort...." That will just allow every host and override anything in code, surely? – Mardoxx Sep 23 '16 at 16:05
0

Put:

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, HEAD, OPTIONS" />
    <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
  </customHeaders>
</httpProtocol>

in the Web Config, this literally covers everything and will let through everything according to the "*" wildcard. If you want concrete domains to be whitelisted you put them into:

<add name="Access-Control-Allow-Origin" value="*" />

Enabling you can do either through global configuration as you have been doing or instead with an attribute:

[EnableCors(origins: "*", headers: "*", methods: "*")]

On the relevant controller. Its one of the two, if you use both options it will choke.

Also you can write your own attribute which can handle loading of origins, headers and methods from a web.config appSettings or from a database by overriding EnableCors attribute if you prefer but that is already beyond the scope of your question I think.

qubits
  • 925
  • 2
  • 14
  • 39