Cross-Origin Resource Sharing (CORS) in ASP.NET Core

Cross-Origin Resource Sharing (CORS) deals with sharing of restricted resources requested from outside the domain which made the request. Check out this Wikipedia article for a good over view of the subject.  If you read the post on Aurelia with an ASP.NET Core API then you might recall that cross-origin requests had to be enabled to allow the front end project to communicate with the API project.

When working on the post mentioned above I only spent enough time on the CORS options in ASP.NET Core to get the sample up and running. This post is going to expand on the path I used to get my sample working and explore some of the options ASP.NET Core offers. The official ASP.NET docs were very helpful in this exploration.

Starting point

In the API project the following was added in the Configure function of Startup in to allow any request regardless of headers, method or origin.

app.UseCors(builder =>
    {
        builder.AllowAnyHeader();
        builder.AllowAnyMethod();
        builder.AllowAnyOrigin();
    }
);

Limiting CORS

The above leaves the site wide open for cross-origin requests. Unless you have a need to allow any request it seems like a good idea to limit CORS. Keep in mind I am pretty new to the subject and my sure there are many nuances that will need to play into a live CORS strategy. For example the following limits CORS request to the two domains listed and only allows GET and POST.

app.UseCors(builder =>
    {
        builder.WithOrigins("http://google.com", "http://elanderson.net")
               .WithMethods("GET", "POST")
               .AllowAnyHeader();
    }
);

Note that origins are identified by scheme, host and port all being the same. For example all of the following would be considered different origins.

URLs with different origins
http://google.com
https://google.com
http://www.google.com
https://www.google.com
http://google.com:5000
https://google.com:5000
http://google.com:6000
https://google.com:6000
http://bing.com

Set CORS on a Controller or Action

MVC doesn’t force the whole site to use the same CORS settings. Just like with authorization CORS can be set by Controller or Action. To use this style of CORS ConfigureServices function of the Startup class needs to add CORS as a service and setup one or more policies. The name of the policy will be used with EnableCores attribute to specify where the policy is applied.

In ConfigureServices add app.AddCors which will allow additions of policies and make the available to controllers and actions. The following example adds an “AllowGoogle” CORS policy that allows http://google.com with any header and any method.

services.AddCors(options =>
{
    options.AddPolicy("AllowGoogle",
        builder => builder.WithOrigins("http://google.com")
                          .AllowAnyHeader()
                          .AllowAnyMethod());
});

Then to apply this policy to a controller or an action add the EnableCors attribute. The following example is applying “AllowGoogle” policy to the whole HomeController.

[EnableCors("AllowGoogle")]
public class HomeController : Controller

Now if you want to exempt the Index from the “AllowGoogle” CORS policy use the DisableCors attribute.

[DisableCors]
public IActionResult Index()

Wrapping up

I am sure the CORS subject goes much deeper than what I covered today, but I wanted to share what I have learned so far as it applies to ASP.NET Core. If you have more resources or have something to add please leave a comment.

5 thoughts on “Cross-Origin Resource Sharing (CORS) in ASP.NET Core”

  1. By default in VS2015, with .NetCore 1.1, a web api template adds some “Access-Control-Allow…” tags to the web.config. These seem to be interupting the CORS settings laid out in this tutorial. I’m submitting API calls with AJAX, and I’m getting preflight errors, specifically about the “Access-Control-Allow-Origin” tag. But removing those tags also causes preflight errors. If I’ve set my cors specs in the startup.cs file, how to I get it to ignore the web.config settings.

    1. stephen I checked the sample I used for this blog and it doesn’t have an entry in the web.config. I don’t have an answer for your question. If you want to post your code somewhere I would be happy to look at it and see if I can found away around your issue.

      If you happen to find an answer please post it in case others hit the same issue.

      1. I’m not sure how I ended up with that web.config, I just opened a new project and it didn’t come with it. I must have picked a different template. The workaround I found for my project however was to create a CorsPolicyBuilder object, add the “WithOrigins” method to it, then run the .Build() method of the builder in the options.AddPolicy line of the AddCors method. Also, being somewhat new to programming, where is the best place to upload code snippets for showing online?

        1. Glad you got your issue worked out. Thank you for posting you for posting your resolution. Looks like you located GitHub would be what I would have recommended you use to share your code. GitHub has a feature that is called a Gist that is a great way to share code without having to create a full repo.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.