5

Fighting with CORS. I have a site that is making a simple XmlHttpRequest to a WEB API I built in C#.

    var xhr = new XMLHttpRequest();
    xhr.open("GET","https://server/controller/method", true);
    xhr.send();

In my web.config I have done the following:

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

I have also tried installing the Nuget package and doing the following in my WebApiConfig.cs

var cors = new EnableCorsAttribute(
            origins: "*",
            headers: "*",
            methods: "*");
        config.EnableCors(cors);

Despite these efforts, CORS still does not work. In the FireFox console, I get the following error:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://server. This can be fixed by moving the resource to the same domain or enabling CORS.

IE also just fails and gives no error.

According to everything I have read, one of these solutions should work, yet they don't. Does something need to be enabled/changed in the client JavaScript? Does CORS not work when you run it in Visual Studio IIS Express on localhost:PortNumber? What am I missing?

sideshowbarker
  • 62,215
  • 21
  • 143
  • 153
Dave
  • 1,969
  • 2
  • 21
  • 39

2 Answers2

2

In your client JavaScript code, you could try adding this:

xhr.withCredentials = true;

As indicated in Firefox CORS request giving 'Cross-Origin Request Blocked' despite headers:

otherwise Firefox failed to use the client cert when making the request

However if you make that change to your client code, you’ll also need to change your server-side code so the value of Access-Control-Allow-Origin is not *. There are a few ways to do that…

From IIS config, you can do it with the URL Rewrite Module by adding the following to your Web.config or ApplicationHost.config file in %SystemDrive%\inetpub\wwwroot\.

<configuration> 
    <system.webServer> 
        <rewrite> 
            <outboundRules> 
                <rule name="Make Access-Control-Allow-Origin echo Origin"> 
                    <match serverVariable="RESPONSE_Access-Control-Allow-Origin"
                           pattern=".+" negate="true" /> 
                    <action type="Rewrite" value="{HTTP_ORIGIN}" /> 
                </rule> 
            </outboundRules> 
        </rewrite> 
    </system.webServer> 
</configuration>

If the above doesn’t work, then you can try the version in the answer over at CORS in IIS issue with credentials and wildcard in Access-Control-Allow-Origin.

Another way to do it is, in the global.asax or other code for your service, add something like this:

if (ValidateRequest()) {
    Response.Headers.Remove("Access-Control-Allow-Origin");
    Response.AddHeader("Access-Control-Allow-Origin", Request.Headers["origin"]);
    Response.Headers.Remove("Access-Control-Allow-Credentials");
    Response.AddHeader("Access-Control-Allow-Credentials", "true");
    Response.Headers.Remove("Access-Control-Allow-Methods");
    Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
}

...the most important part of that being this:

Response.AddHeader("Access-Control-Allow-Origin", Request.Headers["origin"]);

And if neither of those work, try an approach using Microsoft.AspNet.WebApi.Cors.

Community
  • 1
  • 1
sideshowbarker
  • 62,215
  • 21
  • 143
  • 153
0

You need a few more lines in your web.config than you already have:

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    <add name="Access-Control-Allow-Credentials" value="true" />
  </customHeaders>
</httpProtocol>

you cant just say "allow everything", because all the protocols are off by default, so the protocols must be specified too, and if you are ever looking to do any sort of login method over your requests, i would advice Allow-Credentials, otherwise that line can be removed.

You also need to make sure that this is all contained within the system.webServer section.

bizzehdee
  • 17,878
  • 9
  • 41
  • 70
  • Thanks bizzehdee, but the same problem occurs. I have verified that they settings are contained within the system.webServer sections as well. – Dave Feb 16 '17 at 16:38