How to use CORS in ASP.NET Core

By FoxLearn 12/19/2024 2:52:19 PM   212
In this article, we will explore one of the challenges users faced in the early days of web development the Same-Origin Policy (SOP) and how Cross-Origin Resource Sharing (CORS) became a solution.

We’ll discuss what the Same-Origin Policy is, how CORS works to circumvent its limitations, and provide a practical guide to implementing CORS in an ASP.NET Core application.

asp.net core cors

The Same-Origin Policy and User Agents

User agents (UAs), such as web browsers, are client applications used for communication in a client-server architecture. These user agents group URIs into protection domains called “origins.” Two URIs share the same origin if they have identical scheme, host, and port values.

The Same-Origin Policy restricts web applications from making requests to a different origin than the one it was loaded from. These restrictions prevent unauthorized data sharing and limit potentially unsafe HTTP requests to external origins.

For example, a web app running on https://example.com cannot access resources hosted on https://api.example.com unless explicitly permitted.

What is CORS?

Cross-Origin Resource Sharing (CORS) is a W3C standard that allows browsers and servers to interact securely across origins. It achieves this by using HTTP headers to manage cross-origin requests and responses. CORS ensures that both the browser and server share enough information to determine whether a request should be allowed.

However, exposing APIs to foreign origins poses risks, as it may open avenues for malicious attacks.

Example of a CORS Policy:

1
2
3
4
Access-Control-Allow-Origin: https://foo.example.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET
Access-Control-Allow-Headers: Content-Type

This policy permits the origin https://foo.example.com to make GET requests. It also allows cookies and specifies that the Content-Type header is acceptable.

For HTTP methods other than GET or POST with certain MIME types, browsers send a preflight request using the OPTIONS method. This preflight checks with the server whether the main request is allowed.

When a CORS policy is violated, browsers block the request and display an error in the developer console.

JavaScript code cannot access detailed error information for security reasons. The only way to investigate is by checking the browser console.

How to Implement CORS in ASP.NET Core

To demonstrate CORS in action, let’s build a solution with a client-side application that makes AJAX calls to a server-side API.

The client-side application will contain a button that triggers an AJAX POST request to the server-side API.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$.ajax({
    type: "POST",
    crossDomain: true,
    contentType: "application/json",
    dataType: "json",
    data: JSON.stringify({
        FirstName: "John",
        LastName: "Doe",
        Email: "john.doe@example.com",
        IsActive: true
    }),
    success: function(response) {
        console.log("Customer created successfully", response);
    },
    error: function(response) {
        console.log("Error creating customer", response);
    }
});

Without enabling CORS on the server, these requests would fail due to the Same-Origin Policy.

Configuring CORS in ASP.NET Core 3.1

In the Startup.cs file, declare a string for the policy name:

1
readonly string allowSpecificOrigins = "_allowSpecificOrigins";

Add the following code in the ConfigureServices method:

1
2
3
4
5
6
7
8
9
10
11
12
13
public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy(allowSpecificOrigins,
        builder =>
        {
            builder.WithOrigins("https://localhost:44380")
                   .AllowAnyHeader()
                   .AllowAnyMethod();
        });
    });
}

Add the following code in the Configure method to enable CORS in the Middleware.

1
2
3
4
5
6
7
8
9
10
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();
    app.UseCors(allowSpecificOrigins);
    app.UseHttpsRedirection();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Ensure app.UseCors() is placed after app.UseRouting() but before app.UseHttpsRedirection().

After enabling CORS, the client’s AJAX requests should succeed, and the API will return the expected responses without any CORS errors.

For newer versions of ASP.NET Core (greater than 3.1)

In the Program.cs file, define a named or default policy.

1
2
3
4
5
6
7
8
9
10
11
12
var builder = WebApplication.CreateBuilder(args);
 
// Add CORS services to the container
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowSpecificOrigins", policy =>
    {
        policy.WithOrigins("https://example.com") // Replace with your client app's URL
              .AllowAnyHeader()
              .AllowAnyMethod();
    });
});

Add the CORS middleware to the request pipeline in Program.cs. Ensure it is properly placed in the middleware order.

1
2
3
4
5
6
7
8
var app = builder.Build();
 
// Enable CORS for the application
app.UseCors("AllowSpecificOrigins");
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

After completing the setup, test by sending cross-origin requests from your client application. If the server configuration is correct, you should no longer encounter CORS errors.