.NET API CORS: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header.NET API

What to do if you get the following error in the browser when calling a CORS protected .NET Core API endpoint:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 405.

CHECK 1: ALLOW METHOD “OPTIONS”:

A preflight request is a request that the browser issues to check if the CORS settings are implemented correct.

So if your endpoint is a POST, PUT or DELETE endpoint, and the browser sends a request with type “application/json“, the browser sends 2 requests, first the “OPTIONS” request, followed by a POST, PUT or DELETE.

In the CORS settings of your application, you must therefore also allow OPTIONS:

app.UseCors(builder =>
{
  builder
     .WithOrigins("http://localhost:4200", "https://localhost:4200")
     .SetIsOriginAllowedToAllowWildcardSubdomains()
     .AllowAnyHeader()
     .AllowCredentials()
     .WithMethods("GET", "PUT", "POST", "DELETE", "OPTIONS")
     .SetPreflightMaxAge(TimeSpan.FromSeconds(3600));
}
);

CHECK 2: CORS IS DEFINED TWICE IN YOUR CODE:

Check that you have defined CORS twice.

First add CORS to the WebApplicationBuilder Services:

var builder = WebApplication.CreateBuilder();
...
...
builder.Services.AddCors();

Then when defining the app:

var app = builder.Build();
app.UseCors(builder =>
      {
        builder
              .WithOrigins("http://localhost:4200", "https://localhost:4200")
              .SetIsOriginAllowedToAllowWildcardSubdomains()
              .AllowAnyHeader()
              .AllowCredentials()
              .WithMethods("GET", "PUT", "POST", "DELETE", "OPTIONS")
              .SetPreflightMaxAge(TimeSpan.FromSeconds(3600));

      }
);

CHECK 3: CHECK THE SEQUENCE OF CALLS:

You must define CORS before you map controllers, define routes etc.

var app = builder.Build();

// The first thing in the chain of calls is to define the CORS
app.UseCors(builder =>
      {
        builder
              .WithOrigins("http://localhost:4200", "https://localhost:4200")
              .SetIsOriginAllowedToAllowWildcardSubdomains()
              .AllowAnyHeader()
              .AllowCredentials()
              .WithMethods("GET", "PUT", "POST", "DELETE", "OPTIONS")
              .SetPreflightMaxAge(TimeSpan.FromSeconds(3600));

      }
);

...
...

// After that, I can do mapping, routing, redirection etc...
app.MapControllers();
app.UseRouting();
app.UseHttpsRedirection();

if (app.Environment.IsProduction())
{
  app.UseTokenAuthentication();
}

app.Run();

CHECK 4: YOUR LOAD BALANCER MUST ALLOW “OPTIONS” AS WELL

Do you have a load balancer in front of your API? Make sure that the load balancer allows OPTIONS methods as well.

You are now a Cross-Origin Resource Sharing expert. Happy coding.

MORE TO READ:

About briancaos

Developer at Pentia A/S since 2003. Have developed Web Applications using Sitecore Since Sitecore 4.1.
This entry was posted in .net, .NET Core, c# and tagged , , , . Bookmark the permalink.

1 Response to .NET API CORS: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header.NET API

  1. Pingback: .NET Core Caching in your API using AddResponseCaching and ResponseCache attribute | Brian Pedersen's Sitecore and .NET Blog

Leave a comment

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