Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# WEB API CORS does not work

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?

like image 602
Dave Avatar asked Oct 30 '22 11:10

Dave


1 Answers

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

xhr.withCredentials = true;

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

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

But if you make that change to your client code, you also must 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: 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.

like image 193
sideshowbarker Avatar answered Nov 12 '22 21:11

sideshowbarker