In this post, we are going to talk about enabling CORS in ASP.NET Core Web Applications.

Recommended Articles

You can find the source code for this blog post on GitHub.

This post is divided into the following sections:

Before we understand how to enable CORS in ASP.NET Core applications, we need to understand an important concept in the web application security model called the Same-Origin policy.

About Same-Origin and What it Means

Two URLs are considered to have the same origin if they have the same URL scheme (HTTP or HTTPS), same hostname (domain name) and same port number (the endpoint at which applications talk to each other).

What Is the Same-Origin policy?

The Same-origin policy states that a Web browser will only allow communication between two URLs if they belong to the same origin. That is, the client app ( https://example.com ) cannot communicate with the server app ( https://example.net ) as they belong to a different origin. This policy exists to isolate potentially malicious scripts from harming other documents on the web.

Let’s come to the core of the article.

What Is CORS?

But there are some cases where Cross-Domain scripting is desired and the idea of the open web makes it compelling.

Cross-Origin Resource Sharing is a mechanism to bypass the Same-Origin policy of a Web browser. Specifically, a server app uses additional HTTP headers to tell a browser that it is fine to load documents (from its origin) in a few selected client apps (of different origin).

Let’s go deep.

How Does CORS Work?

In this section, let’s learn how CORS works at the level of HTTP messages.

Inner Workings

Let’s have a look at the picture below. There is a client app ( https://example.com ) sending a GET request to a server app ( https://example.net ) for some resource:

All modern browsers set the Origin header automatically, which indicates the domain of the site is making the request.

If the server allows Cross-origin requests from the Origin ( https://example.com ), it sets the Access-Control-Allow-Origin header with its value matching the origin header’s value from the request.

In another way, if the server doesn’t include this header, the request fails. The browser shall receive the response data, but this data shall not be accessible to the client.

That’s how a simple CORS request works.

Preflight Requests

Sometimes, instead of a simple GET request, a client may need to send requests like PUT, DELETE, etc. For such requests, the browser sends an additional request (an OPTIONS request) called a Preflight request. This is done just before the actual request to make sure that the original request succeeds. If it does, the browser sends the actual request.

This diagram illustrates such a scenario:

A preflight request

Actual request

Demo

Enough of the theory. Let’s get to the action.

Same-Origin Policy in Action

In the demo, let’s create two projects. One is a server app which we are going to deploy to Azure. And the other the client app, which we are going to run locally.

Additional read: You can see the CORS in action with .NET Core and Angular projects by reading the .NET Core tutorial.

In Visual Studio, let’s create an MVC project. This will be our server app:

If you are new to Azure deployment, then check out this article. You can also get a free Azure account here.

Once the project is created, let’s deploy it to Azure Web App:

After deployment, the server app is hosted at testapp1158.azurewebsites.net :

Next, let’s create a Client app. Again, we are going to create another ASP.NET Core MVC project, which runs locally. We have both a client and the server app running and they belong to different origins.

To make cross-origin requests, let’s go to Solution Explorer, navigate to Views -> Home -> Index.html . Let’s go to the bottom of the document and add the following piece of code:



<div> <input type="button" value="Try" onclick="CORSRequest()" /> <span id='data'>(Result)</span> </div>

This markup creates a button and, when the user clicks the button, it calls a function.

Just below the markup, let’s create a script tag with the code that makes an ajax request to the server app when the user clicks the button:



<script> var serviceUrl = 'http://testapp1158.azurewebsites.net'; function CORSRequest() { var method = $('#method').val(); $.ajax({ type: method, url: serviceUrl }).done(function (data) { $('#data').text(data); }).error(function (jqXHR, textStatus, errorThrown) { $('#data').text(jqXHR.responseText || textStatus); }); } </script>

Since we haven’t enabled CORS on the server app, the server app doesn’t set any headers and the browser rejects the response.

So, if we navigate to the client app running locally and click the Try button, we should see an error:

Okay! Let’s get to the best part.

Enabling CORS

Now that we have seen the Same-Origin policy in action, let’s enable CORS.

There are 3 steps to enable CORS in a server app:

First of all, we need the Microsoft.AspNetCore.Cors package in our project. It should be already installed in our project. But if for some reason, you can’t see that package in the Solution Explorer, g o to Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution . Search for Microsoft.AspNetCore.Cors and install the package

o to -> -> . Search for and install the package Next, we need to inject CORS into the container so that it can be used by the application. In Startup.cs class, let’s go to the ConfigureServices method and register CORS:



public void ConfigureServices(IServiceCollection services) { services.AddCors(); services.AddMvc(); }

To enable CORS for our application, let’s add the CORS middleware to the HTTP request pipeline in the Configure method, just below the if-else statement. Let’s specify URL from where the CORS requests are allowed when building the CORS policy. Here, we have given the Client URL:

app.UseCors(builder => builder.WithOrigins("http://localhost:55294"));

Let’s save our Server app and re-publish it to the App Service. Now let’s open the client app and click the Try button. We should see an HTML document retrieved from the server app:

Congratulations! We have successfully enabled CORS.

Okay, but that’s not all. Let us show you a few more tricks.

Configuring CORS Requests

If we only want to allow CORS requests to a selected few methods, instead of enabling CORS at the entire application level, we can also enable CORS at the controller level or at the action level.

So to enable CORS at the Action level, let’s replace the code we added previously in the ConfigureServices method with:



public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("AllowOrigin", builder => builder.WithOrigins("http://localhost:55294")); }); services.AddMvc(); }

AllowOrigin

Configure

, we are going to select this policy at runtime at the Action level.

This method defines a named CORS policy called,that allows cross-origin requests from our client app. And now, instead of specifying CORS middleware in the HTTP request pipeline in themethod

So, in our server app, let’s go to Controllers -> HomeController.cs and add the EnableCors decorator to the Index method:



[EnableCors("AllowOrigin")] public IActionResult Index() { return View(); }

Let’s save the project and deploy the server app to Azure again .

In the client app, in the Index.cshtml file, let’s update the serviceURL in the script section:



var serviceUrl = 'http://testapp1158.azurewebsites.net/Home/Index';

Now, if we run the project without debugging, we should still see the output:

But, if we update the serviceUrl in a client app to access any other method in Home Controller in the server app, we should see an error output. The updated serviceURL :



var serviceUrl = 'http://testapp1158.azurewebsites.net/Home/About';

shall give the expected output as:

Similarly, we can do this per controller as well.

It’s not over. More power to you.

Configure CORS Policy Options

In ASP.NET Core, we can use various options to customize our CORS policy.

For example, to only allow GET methods on our resource, let’s use the WithMethods method when we define the CORS policy:



services.AddCors(options => { options.AddPolicy("AllowOrigin", builder => builder.WithOrigins("http://localhost:55294") .WithMethods("GET")); });

If we need to allow any origin to access the resource, let’s use

AllowAnyOrigin

instead of

WithOrigins

:

services.AddCors(options => { options.AddPolicy("AllowOrigin", builder => builder.AllowAnyOrigin()); });

And ASP.NET C ore provides several tools to customize what kind of requests we would like to allow.

In Addition, you can see how CORS is important while working with SignalR in .NET Core by reading .NET Core with SignalR Real-Time Charts.

Conclusion

In conclusion, think of CORS as a relaxation attempt to the more restrictive Same-Origin policy. On the one side, there is a growing need for security on the web. And on the other, there is a need to integrate web services. CORS provides rich tools for our need for an open and secure web and ASP.NET Core allows us to take advantage of CORS in our cross-platform web applications.