Enable Cross-Origin Resource Sharing (CORS) Request in Web API

Introduction

Browser security does not allow webpages to make AJAX requests to another domain. This prevention is called "same-origin policy". This prevents another site from reading sensitive data from another site. Due to how we deploy, it might happen that our web API and web page is in a different domain.

Cross-Origin Resource Sharing (CORS) is a W3C standard. Using CORS, a server can allow some cross-origin (domain) requests and reject others. CORS is more flexible and safer than the earlier techniques such as JSONP.

For example, we have two projects, one is Web API with a web client that calls the web server. Both applications are hosted at different domains, so an AJAX request from the client to the server is a cross-origin request.

 

Figure 1: Cross-Origin Request

Problem statement

When we make a cross-origin request to a web server app using the HTTP method, the web server app does not support CORS and it will return an error when we try to call it.

 

Figure 2: API Tester

Solution

We need to use the following procedure to enable CORS for the web server.

Step 1

To enable CORS in the web server app, we need to first add CORS from the NuGet package. To install CORS from the Nuget package, open the Package Manager Console and run the following command:

  1. Install-Package Microsoft.AspNet.WebApi.Cors  

This command installs the latest package and updates all the dependencies. If you want a specific version of CORS, then use the "-version" flag with this command.

Step 2

Register CORS in WebApiConfig file.

To register CORS, open App_Start/WebApiConfig.cs and add following code to the WebApiConfig.Register method.

  1. public static void Register(HttpConfiguration config)  
  2. {  
  3.     config.EnableCors();  
  4.   
  5.     // Web API configuration and services  
  6.   
  7.     // Web API routes  
  8.     config.MapHttpAttributeRoutes();  
  9.   
  10.     config.Routes.MapHttpRoute(  
  11.         name: "DefaultApi",  
  12.         routeTemplate: "api/{controller}/{id}",  
  13.         defaults: new { id = RouteParameter.Optional }  
  14.     );  
  15. }  

The preceding code enables CORS for all domains. We can enable it for a specific domain using the EnableCors attribute. In this attribute, we need to define a comma-separated list of origin, a comma-separated list of headers and a comma-separated list of methods supported by the resource. We can also use "*" to allow all and null or empty to allow none.

  1. var cors = new EnableCorsAttribute("http://abc.com""*""*");  
  2. config.EnableCors(cors);  

To allow all domains, use following code:

  1. var cors = new EnableCorsAttribute("*""*""*");  
  2. config.EnableCors(cors);  

Enable CORS for Token middleware Provider

The preceding section assists us to enable CORS for the web API only, not for the Token middleware Provider that the client requested to issue the token using OWIN.

To resolve the issue, we need to add the header "Access-Control-Allow-Origin" when the provider issues the token. In the “GrantResourceOwnerCredentials”, we need to add the following code:

  1. public override async Task GrantResourceOwnerCredentials( OAuthGrantResourceOwnerCredentialsContext context)  
  2. {  
  3.     context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin"new[] { "*" });  
  4.     …..  
  5.     …..  
  6. }  

Test Application Output

 

Figure 3: Output

Summary

This article explained how to enable CORS in the Web API and also resolve issues that we were experiencing using the new Web API 2 bearer token feature from AngularJs client.