How to solve ASP.NET Web API CORS Preflight issue when using PUT and DELETE requests with multiple origins? How to solve ASP.NET Web API CORS Preflight issue when using PUT and DELETE requests with multiple origins? asp.net asp.net

How to solve ASP.NET Web API CORS Preflight issue when using PUT and DELETE requests with multiple origins?


I was able to solve my problem by further customizing the Application_BeginRequest method in Global.asax.cs, like this:

protected void Application_BeginRequest(){    if (Request.HttpMethod == "OPTIONS")    {        Response.StatusCode = (int)HttpStatusCode.OK;        Response.AppendHeader("Access-Control-Allow-Origin", Request.Headers.GetValues("Origin")[0]);        Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");        Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");        Response.AppendHeader("Access-Control-Allow-Credentials", "true");        Response.End();    }}

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:

var cors = new EnableCorsAttribute("http://localhost:63342,http://localhost:63347,http://localhost:63345", "*", "*");cors.SupportsCredentials = true;config.EnableCors(cors);

Also, if you're using AngularJS like I am, you must configure $http to use credentials. This can be configured globally like this:

angular.module('Application').config(['$httpProvider',    function config($httpProvider) {        $httpProvider.defaults.withCredentials = true;    }]);

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:


Create custom attribute using ICorsPolicyProvider something like following to check if the requested origin is allowed or not

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,AllowMultiple = false)]    public class EnableCorsForAPIKeysAttribute :      Attribute, ICorsPolicyProvider, IFilter    {        public async Task<CorsPolicy> GetCorsPolicyAsync(          HttpRequestMessage request, CancellationToken cancellationToken)        {            var corsRequestContext = request.GetCorsRequestContext();            var originRequested = corsRequestContext.Origin;            if (await IsValidOrigin(originRequested)) //Check if requested origin is valid or not            {                // Grant CORS request                var policy = new CorsPolicy                {                    AllowAnyHeader = true,                    AllowAnyMethod = true                };                policy.Origins.Add(originRequested);                return policy;            }            else            {                // Reject CORS request                return null;            }        }        public bool AllowMultiple { get {return false;} }    }

To use it, add it to your API controller

[EnableCorsForAPIKeys]public class APIBaseController : ApiController{}