I have an ASP.NET web API that is being called by three different SPA. I am using windows authentication for the web API. I initially tried to configure CORS in the Web.config like this:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://localhost:63342" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
</httpProtocol>
This caused this preflight issue:
Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin (...) is therefore not allowed access.
that I solved by adding the following method in Global.asax.cs:
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Flush();
}
}
This approach worked perfectly for a single SPA. I thought that I could go to the Web.config and add the other origins like this:
<add name="Access-Control-Allow-Origin" value="http://localhost:63342,http://localhost:63347,http://localhost:63345/>
but apparently that is not allowed. This produced the following error:
The 'Access-Control-Allow-Origin' header contains multiple values (...), but only one is allowed. Origin (...) is therefore not allowed access.
So in order to try and fix this, I changed my approach and instead decided to try to configure CORS on the WebAPIConfig.cs, in the Register method like this:
var cors = new EnableCorsAttribute("http://localhost:63342,http://localhost:63347,http://localhost:63345", "Origin, X-Requested-With, Content-Type, Accept", "GET, POST, PUT, DELETE");
cors.SupportsCredentials = true;
config.EnableCors(cors);
I thought this would work but now I have the preflight error again when using PUT and DELETE requests and I don't know how to fix this. I debugged the Application_BeginRequest method and it is still flushing the OPTIONS request so I have no idea of what is causing this error. Does anyone know how I can solve this issue?
EDIT:
The print of the preflight error:
Create custom attribute using
ICorsPolicyProvider
something like following to check if the requested origin is allowed or notTo use it, add it to your API controller
I was able to solve my problem by further customizing the Application_BeginRequest method in Global.asax.cs, like this:
What this code does is add the missing headers to the OPTIONS response (preflight request) that were causing the preflight error. Since I have different origins calling my web API, I'm using
Request.Headers.GetValues("Origin")[0])
to set the origin in the response dinamically.In the WebApiConfig.cs I still specified the different origins but used wildcards on the headers and methods, as well as setting the
SupportsCredentials
to true, like this:Also, if you're using AngularJS like I am, you must configure $http to use credentials. This can be configured globally like this:
And that's it. This solved my problem. If someone else is still having problems, I recommend reading the following publications, which helped me reach my answer: