How to Setup CORS Policies in ASP.NET Core Web API

This blog explains how to set up CORS policies using default policy, add policy, middleware, endpoint routing, and EnableCors attribute.

What is CORS?

CORS(Cross-Origin Resource Sharing) is a W3C standard that allows a server to relax the same origin policy enforced by the browser. Setting up correct CORS policies, expected clients can communicate ASP.NET Web APIs. If the CORS policy is not configured by Web API then the client application receives the error No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

No ‘Access-Control-Allow-Origin’ header is present on the requested resource

Same Origin Policy

According to Wiki, under this policy, a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin. The same origin is considered only when URI Scheme, Hostname, and port number are identical.

The following two URLs have the same origin

  • https://geeksstore.com/products
  • https://geeksstore.com/products

Following URLs have a different origin

  • https://geeksstore.com/products
  • https://api.geeksstore.com/products
  • http://geeksstore.com/products
  • https://geeksstore.com:9810/products

AddDefaultPolicy

The AddDefaultPolicy method adds a policy to the CORS configuration and makes it the application’s default. You can set up default policy if you just need one policy instead of many named policies for the entire application or for testing purpose Web API should be accessible to all origins, headers, and methods.

The following code adds a default CORS policy to allow any origin, header or method if the environment is development. Open Program.cs file and add this code.

if(builder.Environment.IsDevelopment())
{
    builder.Services.AddCors(options =>
    {
        
        options.AddDefaultPolicy(
            policy =>
            {
                policy.AllowAnyOrigin()
                    .AllowAnyHeader()
                    .AllowAnyMethod();
            });
    });
}

var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseCors();
    

AddPolicy

You can add one or more Custom Policies using AddPolicy method. You can allow specific origins, methods or headers and restrict others to access API.

Change code from Program.cs file as shown below to use the named policy. This policy will allow access from http://geekstore.com and http://geeks.com. All other requests will throw error - No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

var _policyName = "GeeksPolicy";

builder.Services.AddCors(opt =>
{
    opt.AddPolicy(name: _policyName,
    policy =>
    {
        policy.WithOrigins
            ("http://geekstore.com",
                "http://geeks.com")
            .AllowAnyMethod()
            .AllowAnyHeader();
    });
});

var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseCors(_policyName);
    

SetIsOriginAllowedToAllowWildcardSubdomains

If you just use the Policy as described in the previous step, then only the domain used in policy definition can access Web API not the subdomain. So http://geekstore.com will be allowed however http://m.geekstore.com will not be allowed to access API.

To allow subdomains to make requests to API then use SetIsOriginAllowedToAllowWildcardSubdomains method.

builder.Services.AddCors(opt =>
{
    opt.AddPolicy(name: _policyName,
        policy =>
        {
            policy.WithOrigins("https://*.geekstore.com")
                .SetIsOriginAllowedToAllowWildcardSubdomains();
        });
});
    

WithMethods

Your web API might need to be exposed only for getting data and not for any updates. Then you can allow specific HTTP methods.

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: _policyName,
        builder =>
        {
            builder
            .WithOrigins("https://geekstore.com") 
            .WithMethods("GET") // defining the allowed HTTP method
            .AllowAnyHeader(); 
        });
});
    

For other HTTP methods like PUT, Delete

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: _policyName,
    policy =>
    {
        policy.WithOrigins("https://geekstore.com")
            .WithMethods("PUT", "DELETE", "GET");
    });
});
    

WithHeaders

The client can send specific headers with requests to API. Web API will accept these header values. An example of a request header can be AcceptCharset, AcceptEncoding, AcceptLanguage, or a custom header like APIKey.

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: _policyName,
    policy =>
    {
        policy.WithOrigins("https://geekstore.com")
            .WithHeaders(HeaderNames.ContentType, "ApiKey");
    });
});
    

Client can request with headers like

HttpClient = new HttpClient();
HttpClient.DefaultRequestHeaders.Add("ApiKey", "0399-09944");
    

Configure multiple policies

There might be some customization required for policies, you can configure multiple policies as per need of origin or method or header combination as shown below.

builder.Services.AddCors(options =>
{
    options.AddPolicy("WebsitePolicy",
        policy =>
        {
            policy.WithOrigins("https://geeksstore.com")
                    .AllowAnyHeader()
                    .AllowAnyMethod();
        });

    options.AddPolicy("MobilePolicy",
        policy =>
        {
            policy.WithOrigins("https://m.geeksstore.com")
                .WithMethods("GET") 
                    .AllowAnyHeader(); 
        });
});

    

Enable Cors with endpoint routing

All these CORS set up that we discussed previously in this blog are created using .Net Core Middleware, and applicable to all requests. However, you can set up CORS for specific Web API endpont.

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: _policyName,
    policy =>
    {
        policy.WithOrigins
            ("https://m.geeksstore.com",
              "https://geeksstore.com");
    });
});

var app = builder.Build();
app.UseCors();

app.UseEndpoints(endpoints =>
{
    endpoints.MapGet("/products",
        context => context.Response.WriteAsync("products"))
        .RequireCors(_policyName);

    endpoints.MapControllers()
        .RequireCors(_policyName); //for all controllers
});
    

EnableCors with Controller or Action Method

You can use EnableCors with specific Controllers only.

//program.cs

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: "Products",
    policy =>
    {
        policy.WithOrigins
            ("https://m.geeksstore.com",
                "https://geeksstore.com");
    });
});

var app = builder.Build();
app.UseCors();

//API Controller

[EnableCors("Products")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{

}
    

Similarly you can enable it for specific ActionMethod.

If you don't use PolicyName then the default policy will be forced.


//program.cs
builder.Services.AddCors(options =>
{

    options.AddDefaultPolicy(
        policy =>
        {
            policy.AllowAnyOrigin()
                .AllowAnyHeader()
                .AllowAnyMethod();
        });
});


var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseCors();

//API Controller

[EnableCors()]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{

}
    

DisableCors

When you use Middleware to inject CORS policy then it is applied to all controllers and action methods. If you do not want should access a specific Action Method or Controller then you can use DisableCors attribute.

[DisableCors]
public void CalculateProductProfit()
{

}
    

Speak your mind
Please login to post your comment!