346

What I am trying to do

I have a backend ASP.Net Core Web API hosted on an Azure Free Plan (Add default security headers in .Net Core).

I also have a Client Website which I want to make consume that API. The Client Application will not be hosted on Azure, but rather will be hosted on Github Pages or on another Web Hosting Service that I have access to. Because of this the domain names won't line up.

Looking into this, I need to enable CORS on the Web API side, however I have tried just about everything for several hours now and it is refusing to work.

How I have the Client Setup Its just a simple client written in React.js. I'm calling the APIs through AJAX in Jquery. The React site works so I know its not that. The Jquery API call works as I confirmed in Attempt 1. Here is how I make the calls

 var apiUrl = "http://andrewgodfroyportfolioapi.azurewebsites.net/api/Authentication";
 //alert(username + "|" + password + "|" + apiUrl);
 $.ajax({
 url: apiUrl,
 type: "POST",
 data: {
 username: username,
 password: password
 },
 contentType: "application/json; charset=utf-8",
 dataType: "json",
 success: function (response) {
 var authenticatedUser = JSON.parse(response);
 //alert("Data Loaded: " + authenticatedUser);
 if (onComplete != null) {
 onComplete(authenticatedUser);
 }
 },
 error: function (xhr, status, error) {
 //alert(xhr.responseText);
 if (onComplete != null) {
 onComplete(xhr.responseText);
 }
 }
 });

What I have tried


Attempt 1 - The 'proper' way

https://learn.microsoft.com/en-us/aspnet/core/security/cors

I have followed this tutorial on the Microsoft Website to a T, trying all 3 options of enabling it Globally in the Startup.cs, Setting it up on every controller and Trying it on every Action.

Following this method, the Cross Domain works, but only on a single Action on a single controller (POST to the AccountController). For everything else, the Microsoft.AspNetCore.Cors middleware refuses to set the headers.

I installed Microsoft.AspNetCore.Cors through NUGET and the version is 1.1.2

Here is how I have it setup in Startup.cs

 // This method gets called by the runtime. Use this method to add services to the container.
 public void ConfigureServices(IServiceCollection services)
 {
 // Add Cors
 services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
 {
 builder.AllowAnyOrigin()
 .AllowAnyMethod()
 .AllowAnyHeader();
 }));
 // Add framework services.
 services.AddMvc();
 services.Configure<MvcOptions>(options =>
 {
 options.Filters.Add(new CorsAuthorizationFilterFactory("MyPolicy"));
 });
 ...
 ...
 ...
 }
 // This method gets called by the runtime. Use this method to configure 
 //the HTTP request pipeline.
 public void Configure(IApplicationBuilder app, IHostingEnvironment env,
 ILoggerFactory loggerFactory)
 {
 loggerFactory.AddConsole(Configuration.GetSection("Logging"));
 loggerFactory.AddDebug();
 // Enable Cors
 app.UseCors("MyPolicy");
 //app.UseMvcWithDefaultRoute();
 app.UseMvc();
 
 ...
 ...
 ...
 }

As you can see, I am doing everything as told. I add Cors before MVC both times, and when that didn't work I attempted putting [EnableCors("MyPolicy")] on every controller as so

[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller

Attempt 2 - Brute Forcing it

https://andrewlock.net/adding-default-security-headers-in-asp-net-core/

After several hours of trying on the previous attempt, I figured I would try to bruteforce it by trying to set the headers manually, forcing them to run on every response. I did this following this tutorial on how to manually add headers to every response.

These are the headers I added

.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")

These are other headers I tried which failed

.AddCustomHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE")
.AddCustomHeader("Access-Control-Allow-Headers", "content-type, accept, X-PINGOTHER")
.AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Host, User-Agent, Accept, Accept: application/json, application/json, Accept-Language, Accept-Encoding, Access-Control-Request-Method, Access-Control-Request-Headers, Origin, Connection, Content-Type, Content-Type: application/json, Authorization, Connection, Origin, Referer")

With this method, the Cross Site headers are being properly applied and they show up in my developer console and in Postman. The problem however is that while it passes the Access-Control-Allow-Origin check, the webbrowser throws a hissy fit on (I believe) Access-Control-Allow-Headers stating 415 (Unsupported Media Type)

So the brute force method doesn't work either


Finally

Has anyone gotten this to work and could lend a hand, or just be able to point me in the right direction?


EDIT

So to get the API calls to go through, I had to stop using JQuery and switch to a Pure Javascript XMLHttpRequest format.

Attempt 1

I managed to get the Microsoft.AspNetCore.Cors to work by following MindingData's answer, except within the Configure Method putting the app.UseCors before app.UseMvc.

In addition, when mixed with the Javascript API Solution options.AllowAnyOrigin() for wildcard support began to work as well.

Attempt 2

So I have managed to get Attempt 2 (brute forcing it) to work... with the only exception that the Wildcard for Access-Control-Allow-Origin doesn't work and as such I have to manually set the domains that have access to it.

Its obviously not ideal since I just want this WebAPI to be wide opened to everyone, but it atleast works for me on a separate site, which means it's a start

app.UseSecurityHeadersMiddleware(new SecurityHeadersBuilder()
 .AddDefaultSecurePolicy()
 .AddCustomHeader("Access-Control-Allow-Origin", "http://localhost:3000")
 .AddCustomHeader("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, PATCH, DELETE")
 .AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type, Authorization"));
Osama Rizwan
6131 gold badge7 silver badges19 bronze badges
asked Jun 6, 2017 at 0:14
7
  • 3
    For your 415 (Unsupported Media Type) issue, set a Content-Type request header to application/json. Commented Jun 6, 2017 at 0:54
  • 18
    Thanks for spending the time to write a such a descriptive question. Commented Aug 11, 2018 at 21:02
  • 2
    If you are testing using Postman, make sure you set Origin to * or something for the request header, then Attempt #1 should work. Without this header, Access-Control-Allow-Origin will not be returned in the response header. Commented Jan 25, 2019 at 16:59
  • It was the comment below about XMLHttpRequest that did it for me, thanks! Commented Dec 29, 2020 at 21:20
  • I am struggling with the same thing. Since yesterday. I am also trying to brute force it using my custom middleware. Its such a headache Commented Aug 5, 2021 at 16:10

38 Answers 38

1
2
344

Because you have a very simple CORS policy (Allow all requests from XXX domain), you don't need to make it so complicated. Try doing the following first (A very basic implementation of CORS).

If you haven't already, install the CORS nuget package.

Install-Package Microsoft.AspNetCore.Cors

In the ConfigureServices method of your startup.cs, add the CORS services.

public void ConfigureServices(IServiceCollection services)
{
 services.AddCors(); // Make sure you call this previous to AddMvc
 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

Then in your Configure method of your startup.cs, add the following :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
 // Make sure you call this before calling app.UseMvc()
 app.UseCors(
 options => options.WithOrigins("http://example.com").AllowAnyMethod()
 );
 app.UseMvc();
}

Now give it a go. Policies are for when you want different policies for different actions (e.g. different hosts or different headers). For your simple example you really don't need it. Start with this simple example and tweak as you need to from there.

Further reading : http://dotnetcoretutorials.com/2017/01/03/enabling-cors-asp-net-core/

Mauricio Gracia Gutierrez
10.9k7 gold badges81 silver badges114 bronze badges
answered Jun 6, 2017 at 1:16
Sign up to request clarification or add additional context in comments.

13 Comments

XMLHttpRequest cannot load andrewgodfroyportfolioapi.azurewebsites.net/api/Authentication. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost:3000' is therefore not allowed access. The response had HTTP status code 415.
This is unlikely going to work, when you register app.UseCors AFTER `` app.UseMvc()`. Middlewares are executed in the order they are registered
using app.UseCors before app.UseMvc, in Configure method seems to work. For some reason, the sequence does seem to matter.
I had to enable options.DisableHttpsRequirement(); in order for any of this to work. It seems with https cors settings were not applying.
@MindingData Why I need to add UseMVC() in a pure WebAPI project? Is it necessary to load all the MVC stuff to make the CORS works??
|
303
  • In ConfigureServices add services.AddCors(); BEFORE services.AddMvc();

  • Add UseCors in Configure

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

Main point is that add app.UseCors, before app.UseMvc().

Make sure you declare the CORS functionality before MVC so the middleware fires before the MVC pipeline gets control and terminates the request.

After the above method works you can change it configure a specific ORIGIN to accept api calls and avoid leaving your API so open to anyone

public void ConfigureServices(IServiceCollection services)
{
 services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
 {
 builder.WithOrigins("http://localhost:4200").AllowAnyMethod().AllowAnyHeader();
 }));
 services.AddMvc();
}

In the configure method tell CORS to use the policy you just created:

app.UseCors("ApiCorsPolicy");
app.UseMvc();

I just found this compact article on the subject - https://dzone.com/articles/cors-in-net-core-net-core-security-part-vi

Mohammed Osman
4,2763 gold badges33 silver badges30 bronze badges
answered Aug 9, 2017 at 19:53

9 Comments

Just to mention this, in contrast to Configure() the order is not really important here within ConfigureServices()
I used the link in the Further Reader and those steps resolved this error. I wasn't sure where these changes should be placed (I thought the API). The Link confirmed that they should be placed in the API. Thanks for the help. I was totally spinning my wheels with this error.
This works with Asp.Net Core 2.1 and with more importantly with localhost
FYI - The CORS specification also states that setting origins to "*" (all origins) is invalid if the Access-Control-Allow-Credentials header is present. Meaning you cannot use AllowCredentials() with AllowAnyOrigin() like above. To use AllowCredentials() you need to set WithOrigins(). learn.microsoft.com/en-us/aspnet/core/security/…
|
49
 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 { 
 app.UseCors(builder => builder
 .AllowAnyHeader()
 .AllowAnyMethod()
 .SetIsOriginAllowed((host) => true)
 .AllowCredentials()
 );
 }
 public void ConfigureServices(IServiceCollection services)
 {
 services.AddCors();
 }

Edit as per 2025年02月01日:

To enable only specific URLs to use your API:

in program.cs

var builder = WebApplication.CreateBuilder(args);
// some stuff
var app = builder.Build();
var services = builder.Services;
var corsUrls = ["http://localhost:4200"]; // here change or add your urls
if (corsUrls == null)
{
 throw new Exception("CorsUrls not found in appsettings.json");
}
services.AddCors(options =>
{
 options.AddPolicy("CorsApi", builder =>
 {
 builder.WithOrigins(corsUrls)
 .AllowAnyMethod()
 .AllowAnyHeader()
 .AllowCredentials();
 });
}
app.UseRouting();
app.UseCors("CorsApi"); // don't forget to use the cors policy
answered Dec 24, 2019 at 21:02

2 Comments

This answer doesn't "enable CORS", it entirely disables it. CORS exists exists to prevent very real attacks, turning it off entirely is not a solution to the question being asked here.
@user229044 I updated my post and added how to enable cors for specific URLs. At least at the time, a working program is worth more than being frustrated that your program does not work. This was the best comment I could come up with at the time. It's now 5 years past.
42

I created my own middleware class that worked for me, i think there is something wrong with .net core middleware class

public class CorsMiddleware
{
 private readonly RequestDelegate _next;
 public CorsMiddleware(RequestDelegate next)
 {
 _next = next;
 }
 public Task Invoke(HttpContext httpContext)
 {
 httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
 httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
 httpContext.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
 httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
 return _next(httpContext);
 }
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class CorsMiddlewareExtensions
{
 public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder)
 {
 return builder.UseMiddleware<CorsMiddleware>();
 }
}

and used it this way in the startup.cs

app.UseCorsMiddleware();
answered Aug 23, 2017 at 15:55

6 Comments

Very elegant way of running Access-Control-Allow-Origin.
This works on WebAPI and MVC and has no dependencies, Thank you!
I was skeptical about this also, but it worked for me. I tried basically every other method to accomplish this that I could find on the internet, but no matter what the server would not respond with the access headers. This worked great. I'm running aspnetcore 2.1.
You should return cors headers only if client send header "Origin" in request. In original CospMiddleware it looks like this: if (!context.Request.Headers.ContainsKey(CorsConstants.Origin)) return this._next(context);
Maybe "something wrong with .net core middleware class" because you just don't add header "Origin" when testing it with curl or something like this. Browsers add this header automatically when you make a request in js code.
|
25

I was struggling with this for DAYS.

I finally got it to work by moving app.UseCors(CORS_POLICY); to the TOP of Configure().

https://weblog.west-wind.com/posts/2016/sep/26/aspnet-core-and-cors-gotchas

Make sure you declare the CORS functionality before> MVC as the headers have to be applied before MVC completes the request.

<= Even though my app didn't call UseMVC(), moving UseCors() to the top fixed the problem

Also:

  • Microsoft.AspNetCore.Cors used to be a required NuGet package in .Net Core 2 and lower; it's now automatically a part of Microsoft.AspNetCore in .Net Core 3 and higher.
  • builder.AllowAnyOrigin() and .AllowCredentials() CORS options are now mutually exclusive in .Net Core 3 and higher
  • CORS policy seems to require Angular call the server with https. An http URL seemed to give a CORS error regardless of the .Net Core server's CORS configuration. For example, http://localhost:52774/api/Contacts would give a CORS error; simply changing the URL to https://localhost:44333/api/Contacts worked.

Additional note:

In my case, CORS wouldn't work until I moved app.UseCors() above app.UseEndpoints(endpoints => endpoints.MapControllers()).

answered Dec 8, 2019 at 23:18

5 Comments

This one should be the answer if you are using Net Core 3. Thanks for saving my life!
"With endpoint routing, the CORS middleware must be configured to execute between the calls to UseRouting and UseEndpoints. Incorrect configuration will cause the middleware to stop functioning correctly." here learn.microsoft.com/en-us/aspnet/core/security/…
"With endpoint routing, the CORS middleware must be configured to execute between the calls to UseRouting and UseEndpoints. Incorrect configuration will cause the middleware to stop functioning correctly." here learn.microsoft.com/en-us/aspnet/core/security/…
Your reference to using https URL instead of http worked for me. I've been stuck for days trying to figure this out. Thanks!
Glad it helped :)
23

In my case only get request works well according to MindingData's answer. For other types of request you need to write:

app.UseCors(corsPolicyBuilder =>
 corsPolicyBuilder.WithOrigins("http://localhost:3000")
 .AllowAnyMethod()
 .AllowAnyHeader()
);

Don't forget to add .AllowAnyHeader()

answered Oct 14, 2017 at 10:06

2 Comments

Agree with Towhid that AllowAnyHeader() is needed. It let server receives OPTIONS request if HEADER's request is missing something.
The .AllowAnyHeader() did it for me, I had issues with the preflight response.
21

For .Net 6

var builder = WebApplication.CreateBuilder(args);
var apiCorsPolicy = "ApiCorsPolicy";
builder.Services.AddCors(options =>
{
 options.AddPolicy(name: apiCorsPolicy,
 builder =>
 {
 builder.WithOrigins("http://localhost:4200", "https://localhost:4200")
 .AllowAnyHeader()
 .AllowAnyMethod()
 .AllowCredentials();
 //.WithMethods("OPTIONS", "GET");
 });
});
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseCors(apiCorsPolicy);
app.UseAuthorization();
app.MapControllers();
app.Run();

here more examples

answered Feb 3, 2022 at 19:09

3 Comments

Just a note for other .Net newbies who don't know which files do what, this goes in /<YourProjectName>/Program.cs (at least when following the SignalR example on Microsofts website).
However, this doesn't "kick in" until you've [EnableCors] in your controller. Until then CORS does nothing.
@Fandango68 that is not true if you properly set that up. Unless you want to enable it for only specific controllers OR you are using endpoint for per routes. Check this learn.microsoft.com/en-us/aspnet/core/security/…
18

For .NET CORE 3.1

In my case, I was using https redirection just before adding cors middleware and able to fix the issue by changing order of them

What i mean is:

change this:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 {
 ...
 
 app.UseHttpsRedirection(); 
 app.UseCors(x => x
 .AllowAnyOrigin()
 .AllowAnyMethod()
 .AllowAnyHeader());
 ...
 }

to this:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 {
 ...
 
 app.UseCors(x => x
 .AllowAnyOrigin()
 .AllowAnyMethod()
 .AllowAnyHeader());
 app.UseHttpsRedirection(); 
 ...
 }

By the way, allowing requests from any origins and methods may not be a good idea for production stage, you should write your own cors policies at production.

answered Jul 31, 2020 at 9:24

Comments

14

To expand on user8266077's answer, I found that I still needed to supply OPTIONS response for preflight requests in .NET Core 2.1-preview for my use case:

// https://stackoverflow.com/a/45844400
public class CorsMiddleware
{
 private readonly RequestDelegate _next;
 public CorsMiddleware(RequestDelegate next)
 {
 _next = next;
 }
 public async Task Invoke(HttpContext context)
 {
 context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
 context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
 // Added "Accept-Encoding" to this list
 context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Accept-Encoding, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
 context.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
 // New Code Starts here
 if (context.Request.Method == "OPTIONS")
 {
 context.Response.StatusCode = (int)HttpStatusCode.OK;
 await context.Response.WriteAsync(string.Empty);
 }
 // New Code Ends here
 await _next(context);
 }
}

and then enabled the middleware like so in Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
 app.UseMiddleware(typeof(CorsMiddleware));
 // ... other middleware inclusion such as ErrorHandling, Caching, etc
 app.UseMvc();
}
answered Mar 27, 2018 at 18:05

3 Comments

I recommend adding middleware that way: app.Use<CorsMiddleware>();
You can replace those 2 ligne : context.Response.StatusCode = (int)HttpStatusCode.OK; await context.Response.WriteAsync(string.Empty); with a simple : return;
To expand on your expansion of @user8266077's answer: Beware that if the request for some other reason fails, this middleware will throw an exception and the headers will not be set. Meaning that in frontend, it will still look like a CORS issue even though it's something totally different. I bypassed this by catching any exceptions in await _next(context) and setting the status code and response manually if this happens. I also had to add "authorization" to Access-Control-Allow-Headers for the preflight request to work when making requests from react that requires authorization.
13

for ASP.NET Core 3.1 this soleved my Problem https://jasonwatmore.com/post/2020/05/20/aspnet-core-api-allow-cors-requests-from-any-origin-and-with-credentials

public class Startup
 {
 public Startup(IConfiguration configuration)
 {
 Configuration = configuration;
 }
 public IConfiguration Configuration { get; }
 // This method gets called by the runtime. Use this method to add services to the container.
 public void ConfigureServices(IServiceCollection services)
 {
 services.AddCors();
 services.AddControllers();
 }
 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 {
 app.UseRouting();
 // global cors policy
 app.UseCors(x => x
 .AllowAnyMethod()
 .AllowAnyHeader()
 .SetIsOriginAllowed(origin => true) // allow any origin
 .AllowCredentials()); // allow credentials
 app.UseAuthentication();
 app.UseAuthorization();
 app.UseEndpoints(x => x.MapControllers());
 }
 }
answered Oct 27, 2020 at 18:10

Comments

8

None of the above procedures helped and I then read article which solved the issue.

Below is the code.

public void ConfigureServices(IServiceCollection services)
{
 // Add service and create Policy with options
 services.AddCors(options =>
 {
 options.AddPolicy("CorsPolicy",
 builder => builder.AllowAnyOrigin()
 .AllowAnyMethod()
 .AllowAnyHeader()
 .AllowCredentials() );
 });
 services.AddMvc(); 
}

and

public void Configure(IApplicationBuilder app)
{
 // ...
 // global policy - assign here or on each controller
 app.UseCors("CorsPolicy");

and on the top of my actionmethod

[EnableCors("CorsPolicy")]
answered Dec 17, 2018 at 14:04

2 Comments

This is probably a bad idea: you shouldn't mix middleware (app.UseCors()) with [EnableCors()] in the same application. You should use one or the other - but not both: learn.microsoft.com/en-us/aspnet/core/security/…: Use the [EnableCors] attribute or middleware, not both in the same app.
@FoggyDay - not quite correct. You can app.UseCors() with multiple policies and multiple [EnableCors("policyA")] in your controllers. Albeit it's 2022 now. More here learn.microsoft.com/en-us/aspnet/core/security/…
7

Simplest solution is add

 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
 {
 if (env.IsDevelopment())
 {
 app.UseDeveloperExceptionPage();
 }
 else
 {
 app.UseHsts();
 }
 app.UseCors(options => options.AllowAnyOrigin());
 app.UseHttpsRedirection();
 app.UseMvc();
 }

to Startup.cs.

answered Jul 11, 2019 at 7:55

Comments

6

I think if you use your own CORS middleware you need to make sure it is really CORS request by checking origin header.

 public class CorsMiddleware
{
 private readonly RequestDelegate _next;
 private readonly IMemoryCache _cache;
 private readonly ILogger<CorsMiddleware> _logger;
 public CorsMiddleware(RequestDelegate next, IMemoryCache cache, ILogger<CorsMiddleware> logger)
 {
 _next = next;
 _cache = cache;
 _logger = logger;
 }
 public async Task InvokeAsync(HttpContext context, IAdministrationApi adminApi)
 {
 if (context.Request.Headers.ContainsKey(CorsConstants.Origin) || context.Request.Headers.ContainsKey("origin"))
 {
 if (!context.Request.Headers.TryGetValue(CorsConstants.Origin, out var origin))
 {
 context.Request.Headers.TryGetValue("origin", out origin);
 }
 bool isAllowed;
 // Getting origin from DB to check with one from request and save it in cache 
 var result = _cache.GetOrCreateAsync(origin, async cacheEntry => await adminApi.DoesExistAsync(origin));
 isAllowed = result.Result.Result;
 if (isAllowed)
 {
 context.Response.Headers.Add(CorsConstants.AccessControlAllowOrigin, origin);
 context.Response.Headers.Add(
 CorsConstants.AccessControlAllowHeaders,
 $"{HeaderNames.Authorization}, {HeaderNames.ContentType}, {HeaderNames.AcceptLanguage}, {HeaderNames.Accept}");
 context.Response.Headers.Add(CorsConstants.AccessControlAllowMethods, "POST, GET, PUT, PATCH, DELETE, OPTIONS");
 if (context.Request.Method == "OPTIONS")
 {
 _logger.LogInformation("CORS with origin {Origin} was handled successfully", origin);
 context.Response.StatusCode = (int)HttpStatusCode.NoContent;
 return;
 }
 await _next(context);
 }
 else
 {
 if (context.Request.Method == "OPTIONS")
 {
 _logger.LogInformation("Preflight CORS request with origin {Origin} was declined", origin);
 context.Response.StatusCode = (int)HttpStatusCode.NoContent;
 return;
 }
 _logger.LogInformation("Simple CORS request with origin {Origin} was declined", origin);
 context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
 return;
 }
 }
 await _next(context);
 }
answered Mar 6, 2019 at 6:04

1 Comment

Thank you very much. I nearly went nuts, asking myself why the Access-Control-Allow-Origin header was not issued by the server. Actually I sent requests via Postman w/o the Origin header. This saved my day! (Or at least my forenoon ;) )
6

For me the solution was to correct the order:

app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
answered Feb 2, 2021 at 6:58

Comments

6

Here's a .NET 6 example of a Program.cs file using top-level statements to configure CORS. As can be seen, builder.Services.AddCors and app.UseCors are the required statements. The two commented UseCors statements also work and were included to show other options. I made no changes to my ASP.NET API controllers.

For reference, my development Angular app is running on localhost:4200 and is connecting to the development ASP.NET API server using https://localhost:7262.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
 app.UseSwagger();
 app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
//app.UseCors(options => options.WithOrigins("http://localhost:4200").AllowAnyMethod());
//app.UseCors(options => options.WithOrigins("http://localhost:4200").WithMethods(new string[] {"POST", "PUT"}));
app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod());
app.MapControllers();
app.Run();
answered Jan 23, 2022 at 15:52

Comments

5

try adding jQuery.support.cors = true; before the Ajax call

It could also be that the data your sending to the API is wonky,

try adding the following JSON function

 var JSON = JSON || {};
 // implement JSON.stringify serialization
 JSON.stringify = JSON.stringify || function (obj) {
 var t = typeof (obj);
 if (t != "object" || obj === null) {
 // simple data type
 if (t == "string") obj = '"' + obj + '"';
 return String(obj);
 }
 else {
 // recurse array or object
 var n, v, json = [], arr = (obj && obj.constructor == Array);
 for (n in obj) {
 v = obj[n]; t = typeof (v);
 if (t == "string") v = '"' + v + '"';
 else if (t == "object" && v !== null) v = JSON.stringify(v);
 json.push((arr ? "" : '"' + n + '":') + String(v));
 }
 return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
 }
 };
 // implement JSON.parse de-serialization
 JSON.parse = JSON.parse || function (str) {
 if (str === "") str = '""';
 eval("var p=" + str + ";");
 return p;
 };

then in your data: object change it to

 data: JSON.stringify({
 username: username,
 password: password
 }),
Hossein Narimani Rad
32.7k19 gold badges92 silver badges121 bronze badges
answered Jun 6, 2017 at 6:46

1 Comment

Thanks for your help. Definitely utilized a portion of the answer to figure out the solution in the end after combining everyones answers
5

For me, it had nothing to do with the code that I was using. For Azure we had to go into the settings of the App Service, on the side menu the entry "CORS". There I had to add the domain that I was requesting stuff from. Once I had that in, everything was magic.

answered Apr 30, 2019 at 19:48

1 Comment

Oh gosh - thank you (.net 5/6) - spent literally days banging my head against this one. It appears Azure implements its own CORS functionality on APIs and Websites in an App Service. This is not mentioned anywhere in any documentation I've found whilst googling. If you use Azure give this a try!
5

In launchSettings.json, under iisSettings, set anonymousAuthentication to true:

"iisSettings": {
 "windowsAuthentication": true,
 "anonymousAuthentication": true,
 "iisExpress": {
 "applicationUrl": "http://localhost:4200/",
 "sslPort": 0
 }
 }

Then, in Startup.cs, under ConfigureServices, before services.AddMvc, add:

services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
{
 builder
 .AllowAnyOrigin()
 .WithHeaders(HeaderNames.AccessControlAllowHeaders, "Content-Type")
 .AllowAnyMethod()
 .AllowCredentials();
}));

and then, in configure method, before app.UseMvc() add:

app.UseCors("ApiCorsPolicy");
answered Aug 13, 2019 at 14:46

1 Comment

This did it for me, I originally setup my project for Windows Authentication but then had to change it to anonymous, I had CORS correctly configured but this setting in launchSettings.json was the culprit, thank you for posting this!.
4

.NET Core 3.1

Worked for me and how the docs say to do it:

in Startup class:

readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; 

In ConfigureServices() method:

 services.AddCors(options =>
 {
 options.AddPolicy(MyAllowSpecificOrigins,
 builder =>
 {
 builder.WithOrigins("http://example.com",
 "http://www.contoso.com");
 });
 });

In Configure() method:

 app.UseCors(MyAllowSpecificOrigins); 

https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.1

answered Jan 26, 2020 at 14:58

Comments

3

I'm using .Net CORE 3.1 and I spent ages banging my head against a wall with this one when I realised that my code has started actually working but my debugging environment was broken, so here's 2 hints if you're trying to troubleshoot the problem:

  1. If you're trying to log response headers using ASP.NET middleware, the "Access-Control-Allow-Origin" header will never show up even if it's there. I don't know how but it seems to be added outside the pipeline (in the end I had to use wireshark to see it).

  2. .NET CORE won't send the "Access-Control-Allow-Origin" in the response unless you have an "Origin" header in your request. Postman won't set this automatically so you'll need to add it yourself.

answered Mar 27, 2020 at 10:27

Comments

3

Here is my code : )

 app.Use((ctx, next) =>
 {
 ctx.Response.Headers.Add("Access-Control-Allow-Origin", ctx.Request.Headers["Origin"]);
 ctx.Response.Headers.Add("Access-Control-Allow-Methods", "*");
 ctx.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
 ctx.Response.Headers.Add("Access-Control-Allow-Headers", "AccessToken,Content-Type");
 ctx.Response.Headers.Add("Access-Control-Expose-Headers", "*");
 if (ctx.Request.Method.ToLower() == "options")
 {
 ctx.Response.StatusCode = 204;
 return Task.CompletedTask;
 }
 return next();
 });
answered Apr 4, 2020 at 3:06

Comments

2

Based on your comment in MindingData's answer, it has nothing to do with your CORS, it's working fine.

Your Controller action is returning the wrong data. HttpCode 415 means, "Unsupported Media type". This happens when you either pass the wrong format to the controller (i.e. XML to a controller which only accepts json) or when you return a wrong type (return Xml in a controller which is declared to only return xml).

For later one check existence of [Produces("...")]attribute on your action

answered Jun 6, 2017 at 6:06

1 Comment

Thanks for your help. Tried a new solution and played with json being sent out and it worked after I stringified it and got it to work
2

In my case I fixed with UseCors before UserRouting..

answered Apr 24, 2020 at 15:13

1 Comment

I ran into something similar this when I upgraded from dotnet core 2.2 to 3.1. Had to move app.UseCors() above app.UseRouting(). This answer pointed me in the right direction.
1

Simple and easy way to do it.

  1. Install package

Install-Package Microsoft.AspNetCore.Cors

  1. Put this below code in startup.cs file

app.UseCors(options => options.AllowAnyOrigin());

Cray
2,8468 gold badges25 silver badges34 bronze badges
answered Feb 20, 2020 at 10:01

Comments

1

Here is how I did this.

I see that in some answers they are setting app.UserCors("xxxPloicy") and putting [EnableCors("xxxPloicy")] in controllers. You do not need to do both.

Here are the steps.

In Startup.cs inside the ConfigureServices add the following code.

 services.AddCors(c=>c.AddPolicy("xxxPolicy",builder => {
 builder.AllowAnyOrigin()
 .AllowAnyMethod()
 .AllowAnyHeader();
 }));

If you want to apply all over the project then add the following code in Configure method in Startup.cs

app.UseCors("xxxPolicy");

Or

If you want to add it to the specific controllers then add enable cors code as shown below.

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

For more info: see this

answered May 17, 2020 at 5:55

Comments

1

Use a custom Action/Controller Attribute to set the CORS headers.

Example:

public class AllowMyRequestsAttribute : ControllerAttribute, IActionFilter
{
 public void OnActionExecuted(ActionExecutedContext context)
 {
 // check origin
 var origin = context.HttpContext.Request.Headers["origin"].FirstOrDefault();
 if (origin == someValidOrigin)
 {
 context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", origin);
 context.HttpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
 context.HttpContext.Response.Headers.Add("Access-Control-Allow-Headers", "*");
 context.HttpContext.Response.Headers.Add("Access-Control-Allow-Methods", "*");
 // Add whatever CORS Headers you need.
 }
 }
 public void OnActionExecuting(ActionExecutingContext context)
 {
 // empty
 }
}

Then on the Web API Controller / Action:

[ApiController]
[AllowMyRequests]
public class MyController : ApiController
{
 [HttpGet]
 public ActionResult<string> Get()
 {
 return "Hello World";
 }
}
answered Jun 1, 2020 at 4:25

Comments

1

In my case character / at the end of my origin name was causing an issue.

Solution that worked out for me in .NET Core 3.1:

public void ConfigureServices(IServiceCollection services)
{
 services.AddCors(c => c.AddPolicy("PolicyName", policy => {
 policy.WithOrigins("http://localhost:3000")
 .AllowAnyMethod()
 .AllowAnyHeader();
 }));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
 app.UseCors("PolicyName");
}
answered Jul 25, 2020 at 20:33

Comments

1

The solution that worked for me in ASP.NET Core 3.1:

public void ConfigureServices(IServiceCollection services)
 {
 services.AddCors(options =>
 {
 options.AddPolicy("CorsPolicy",
 builder => builder.AllowAnyOrigin()
 .AllowAnyMethod()
 .AllowAnyHeader());
 });
 services.AddControllersWithViews();
 }

and then change the following:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 {
 app.UseCors("CorsPolicy");
 if (env.IsDevelopment())
 {
 app.UseDeveloperExceptionPage();
 }
 else
 {
 app.UseExceptionHandler("/Home/Error");
 // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
 app.UseHsts();
 }
 app.UseHttpsRedirection();
 app.UseStaticFiles();
 app.UseRouting();
 app.UseAuthentication();
 app.UseAuthorization();
 app.UseEndpoints(endpoints =>
 {
 endpoints.MapControllerRoute(
 name: "default",
 pattern: "{controller=Home}/{action=Index}/{id?}");
 });
 }

Then program worked and error was solved.

Dominik
1,4712 gold badges20 silver badges39 bronze badges
answered Jul 27, 2020 at 9:22

Comments

0

I got MindingData's answer above to work, but I had to use Microsoft.AspNet.Cors instead of Microsoft.AspNetCore.Cors. I am using .NetCore Web Application API project in Visual Studio 2019

answered Jun 12, 2019 at 15:30

1 Comment

NOTE: you shouldn't use Microsoft.AspNet.Cors in an ASP.Net Cor application. If you're on .Net Core 3.0 or higher, you don't need to import any NuGet package at all for CORS. If you're on .Net Core 2.3 or lower, then you need the appropriate version of Microsoft.AspNet.Cors from NuGet.
0

The

Microsoft.AspNetCore.Cors

will allow you to do CORS with built-in features, but it does not handle OPTIONS request. The best workaround so far is creating a new Middleware as suggested in a previous post. Check the answer marked as correct in the following post:

Enable OPTIONS header for CORS on .NET Core Web API

answered Feb 12, 2020 at 23:01

Comments

1
2

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.