I need to allow CORS requests from multiple domains from my web API. However, I do not want to let it open for all by doing below in web config.
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
</customHeaders>
</httpProtocol>
</system.webServer>
I need to allow only a whitelist of domains to be able to make the CORS request to my APIs.
I have seen this SO question, however, I do not preferably want to use .htaccess
files as I don't have control over the IIS server.
I have tried this SO answer and this blog.
The problem is, it always returns the below error.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Here's my implementation.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class EnableCORSAttribute : ActionFilterAttribute
{
private string[] origins;
private string[] methods;
public EnableCORSAttribute(string[] origins = null, string[] methods = null)
{
this.origins = origins;
this.methods = methods;
}
public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
{
if (origins == null || !origins.Any())
{
//Allow all
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", "*");
}
else if (origins.Contains(HttpContext.Current.Request.Url.Host, StringComparer.InvariantCultureIgnoreCase))
{
//Allow only if matching
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", HttpContext.Current.Request.Url.Host);
}
if (methods == null || !methods.Any())
{
//Allow all
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Methods", "*");
}
else if (methods.Contains(HttpContext.Current.Request.HttpMethod, StringComparer.InvariantCultureIgnoreCase))
{
//Allow only specified
HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Methods", HttpContext.Current.Request.HttpMethod);
}
}
}
This is how I decorate my BaseController
with the attribute.
[EnableCORS(origins: new string[] { "localhost" }, methods: new string[] { "GET", "POST", "OPTIONS" })]
public class BaseController : ApiController
{
// GET api/<controller>
public HttpResponseMessage Options()
{
return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
}
}
I've also tried to register this attribute from the Global.asax
file.
GlobalFilters.Filters.Add(new EnableCorsAttribute());
RegisterGlobalFilters(GlobalFilters.Filters);
But still get the same error. Not sure what else am I missing.
I have also tried Microsoft.AspNet.WebApi.Cors
Nuget Package and putting this in the WebApiConfig file.
var enableCorsAttribute = new EnableCorsAttribute("http://localhost:59427",
"Origin, Content-Type, Accept, Authorization",
"GET, POST, OPTIONS");
config.EnableCors(enableCorsAttribute);
It works for one domain, but as soon as I add another domain it also starts throwing the same error.