Mastering CORS in ASP.NET Core: A Step-by-Step Guide

What is CORS?

CORS stands for Cross-Origin Resource Sharing.

It’s a security feature implemented by web browsers to control how resources on a web page (like JavaScript code) can request data from a different domain (or origin) than the one the page was served from.


Why can Postman (and other tools) access your API even if CORS restricts the origin?

CORS is a browser security feature only. It is enforced by web browsers—not by the server or the API itself.
Browsers enforce CORS: When JavaScript running in a browser makes a cross-origin HTTP request, the browser checks the CORS policy (headers) sent by the server. If the policy doesn’t allow the requesting origin, the browser blocks the response from being accessible to the JavaScript code.

Tools like Postman don’t use a browser: Postman, curl, or server-side code do not have this browser security layer. They send HTTP requests directly and receive the response without any CORS restrictions.


What this means practically:

Your API is still open and accessible to any client that knows the endpoint URL, regardless of origin.

CORS only protects users accessing your API through browsers. It prevents malicious web pages from calling your API from unauthorized origins.

To secure your API properly, you need other measures like authentication, authorization, API keys, tokens, etc. CORS is just one layer focused on browser security.


Example

Your frontend running on http://localhost:3000 makes a request to http://localhost:5000/api/data.

The browser sends an HTTP request with an Origin: http://localhost:3000 header.

Your API responds with:

Access-Control-Allow-Origin: http://localhost:3000


The browser sees this and allows the frontend to access the response data.

If the API does not send this header, the browser blocks the frontend from reading the response.

What is CORS? Understanding It Through a School Library

Imagine your web browser as a bustling school campus filled with many classrooms. Each classroom represents a different website or app running in your browser.

Now, think of your API as the school library that holds all the valuable information your apps need.

When a student from a classroom (your frontend app) wants to borrow a book (fetch data) from the library (API), the librarian (browser security) checks the student's classroom ID (the origin of the request).

If the librarian sees that the classroom is on the approved list — meaning the student is allowed to borrow books — the request goes through, and the student gets the book.

But if the classroom isn’t on the approved list, the librarian politely denies the request to keep the library’s resources safe.

This simple rule is how CORS (Cross-Origin Resource Sharing) works: it protects users by ensuring that only trusted websites can access resources from your API.

In this blog, we’ll walk you through how to set up CORS in your ASP.NET Core Web API so your frontend apps can safely and easily communicate with your backend.


Pros of CORS

1. Improves Web Security

Prevents unauthorized cross-origin requests, protecting users from malicious websites trying to steal data or perform unwanted actions.

2. Fine-Grained Access Control

Allows servers to specify exactly which domains (origins) can access their resources, headers, and HTTP methods.

Enables selective sharing rather than open access.

3. Standardized & Supported

Built into all modern browsers as a standard security mechanism.

Works seamlessly with existing web protocols (HTTP/HTTPS).

4. Supports Complex Scenarios

Supports preflight requests, credentials sharing, and more advanced configurations, giving flexibility to developers.


Cons of CORS

1. Configuration Complexity

Setting up CORS correctly can be tricky, especially when dealing with multiple origins, credentials, or custom headers.

Misconfiguration can lead to security risks or broken APIs.

2. Only Protects Browser Clients

CORS is enforced by browsers; non-browser clients (e.g., Postman, server-to-server) are not affected.

This means CORS does not replace proper backend security like authentication and authorization.

3. Potential Performance Overhead

Preflight OPTIONS requests add additional round-trips, which can impact performance especially on APIs with many cross-origin requests.

4. Debugging Difficulties

CORS errors can be confusing for beginners because the problem is often related to server configuration, not frontend code.

Browser error messages are sometimes not very descriptive.


How to handle CORS in .NET core 


1. Apply a CORS policy globally to all endpoints.

// Define CORS policy
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowSpecificOrigin", policy =>
    {
        policy.WithOrigins("http://localhost:3000")
              .AllowAnyHeader()
              .AllowAnyMethod();
    });
});

// applies policy 

app.UseCors("AllowSpecificOrigin"); 

 

2. Enable CORS on Specific Controllers or Actions (Attribute-based) 

 Use [EnableCors] attribute to apply CORS policy only to certain controllers or actions.

using Microsoft.AspNetCore.Cors;

[ApiController]

[Route("[controller]")]

[EnableCors("AllowSpecificOrigin")]  // Apply specific policy here

public class MyController : ControllerBase

{

    [HttpGet]

    public IActionResult Get() => Ok("Hello with CORS");

}

Make sure you register the policy in Program.cs as usual.


3. Allow CORS with Default Policy

Register a default policy without naming it, so you can call UseCors() without parameters:

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

...

app.UseCors();  // Applies default policy

 

4. Allow Any Origin (For Development or Testing Only)

Use AllowAnyOrigin() to allow requests from any domain:

builder.Services.AddCors(options =>

{

    options.AddPolicy("AllowAll", policy =>

    {

        policy.AllowAnyOrigin()

              .AllowAnyHeader()

              .AllowAnyMethod();

    });

});

...

app.UseCors("AllowAll");

Warning: Avoid this in production due to security risks.


 5. CORS with Credentials

Allow cookies or authentication headers with CORS. Note: When using AllowCredentials(), you cannot use AllowAnyOrigin()—you must specify explicit origins.

builder.Services.AddCors(options =>

{

    options.AddPolicy("AllowWithCredentials", policy =>

    {

        policy.WithOrigins("https://trustedclient.com")

              .AllowAnyHeader()

              .AllowAnyMethod()

              .AllowCredentials(); // Enable cookies/auth headers

    });

});

...

app.UseCors("AllowWithCredentials");



6. Policy Per Endpoint Using Endpoint Routing

You can specify CORS per endpoint in MapControllers() or MapGet() etc.:

app.UseRouting();

app.UseCors();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers().RequireCors("AllowSpecificOrigin");
});


📝 Check my video tutorial: Video URL

🔧 Tech Stack: ASP.NET Core, .NET 10, Web API

📁 Source Code: Github link


📌 Don't forget to Like, Comment, and Subscribe for more .NET tutorials!

#dotnet #aspnetcore #webapi #CORS #programming #tutorial


Comments

Popular posts from this blog

Understanding Middleware in .NET Core

Database Approaches in .NET Core: Code-First vs Database-First Explained for Beginners

Dev tunnels