Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

ASP.NET Core and CORS Gotchas


:P
On this page:

Interconnected

Last night I was working on updating my ASP.NET Core AlbumViewer sample application to Angular 2.0 and in the process ran into CORS problems. Angular 2.0's default working environment runs a development server off a seperate port which is effectively a seperate domain and all calls back to the main ASP.NET site for the API calls effectively are cross domain calls. Alas those calls failed and upon closer inspection it was due to the fact that the CORS headers weren't getting sent.

CORS Setup in ASP.NET Core

CORS is a server based mechanism that essentially lets a server say:

I allow cross domain calls from the domains I specify

It's good to be king, huh? (especially a king with no clothes since the protocol does next to nothing to prevent malicious attacks but that's a story for another post)

When browsers make cross domain calls using XHR, they request CORS headers to decide whether the target server allows access to the source domain. In this case the source domain is Angular's dev server (localhost:3000) and the target server is my ASP.NET API service (localhost:5000 (raw Kestrel) or localhost/albumviewer (IIS/IIS Express)).

To set up CORS is at least a 3 step process:

  • You register CORS functionality
  • You configure CORS options
  • You apply the functionality

There are a number of different ways to do this but by far the best approach IMHO is to create a CORS policy and then apply that policy either globally to all requests or specific controllers.

I like the policy approach because:

  • It allows me to add CORS and declare the policy in one place
  • It allows the policy to be reused and be applied selectively

Below I use the explicit policy approach.

Register and Define a Policy

To do this start with registering CORS functionality in ConfigureServices() of Startup.cs:

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(); 
}

The AddCors() call above adds the CORS features to ASP.NET and creates a custom policy that can be reused in the application by name. There are other ways to do essentially the same thing by explicitly adding a policy builder in the configuration step but to me this seems cleanest - define one or more policies up front and then apply it.

Apply the Policy

Once the policy has been defined it can be applied.

You can apply the policy globally to every request in the application by call app.useCors() in the Configure() method of Startup:

public void Configure(IApplicationBuilder app)
{
    // ...

    // global policy - assign here or on each controller
    app.UseCors("CorsPolicy");

    // ...
    
    // IMPORTANT: Make sure UseCors() is called BEFORE this
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

UseCors() has to be called before UseMvc()

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

or you can apply the policy to individual controllers:

[EnableCors("CorsPolicy")]
[ApiExceptionFilter]
public class AlbumViewerApiController : Controller

Check that it works

When it's all said and done you now should get the appropriate CORS headers with your response:

HTTP/1.1 200 OK
Date: Tue, 27 Sep 2016 07:09:08 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Vary: Origin
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:3000
Content-Length: 2851

Note that the actual headers sent may vary depending on what your request needs. GET operations might have different CORS headers than a POST or OPTION request.

Watch out for testing CORS without Cross Domain!

So last night I reviewed my code and checked for the CORS functionality. It turns out I had at some point renamed the policy and so the policy strings were out of sync resulting in mismatched policy names and no CORS headers. Once I fixed that it seemed that everything should be well.

I went ahead and tested API calls through a browser and found: No CORS headers. Checked all again for errors and it all looked just fine. WTH? It wasn't until I tried running the full Angular application again that I found that the app was now working, and the CORS headers were being sent properly. In this duh! moment I realized of course that this is the correct behavior.

CORS headers are only sent on cross domain requests and the ASP.NET CORS module is smart enough to detect whether a same domain request is firing and if it is, doesn't send the headers. Duh - of course, but in the heat of the moment I totally didn't think of that.

The sad thing is this is not the first time I've made this mistake :-) As soon as I figured it out, I realized I had made that very same mistake a few months earlier when I set up the original CORS functionality and tested - and failed/flailed. History repeats itself. To avoid that - I'm writing it down to jog my memory.

So, if you're going to test CORS operation the only effective way to do is is by using a cross-site origin to trigger the CORS behavior. Either use a cross site client app (my Angular app in this case) or an HTTP test client (I used my West Wind WebSurge tool with an explicit origin header) and avoid scratching your head on why the CORS headers are not showing up.

Resources

Posted in ASP.NET  ASP.NET  Security  

The Voices of Reason


 

Fabian Gosebrink
September 26, 2016

# re: ASP.NET Core and CORS Gotchas

Thanks for this post. I was looking into this a few days ago. Found this solution: https://github.com/FabianGosebrink/ASPNET-Core-Angular2-StarterTemplate/blob/master/src/ASPNETCoreAngular2Demo/Startup.cs

I was wondering about the many ways to enable CORS and I did not know which one was "right" or "wrong". The only difference between those two solutions is that yours has a specific name which can be excplicitly applied in the
app.UseCors("..."); 

Method.

Or are there any other differences?

BR

Fabian

Rick Strahl
September 26, 2016

# re: ASP.NET Core and CORS Gotchas

@Fabian - yup it's confusing to have a number of different ways to do this. If you look at the actual ASP.NET docs for CORS you see the confusion quite clearly as they try to explain it all in a long and confusing topic.

I think under the covers it all goes into a builder - the different mechanisms are just different ways to create and cache that builder. I like the explicit policy approach because:

* It allows me to add CORS and declare the policy in one place
* It allows the policy to be reused and be applied selectively

Fabian Gosebrink
September 26, 2016

# re: ASP.NET Core and CORS Gotchas

Okay...just needed that to check if my thoughts are correct. Thank you :)

Kristian Hellang
September 26, 2016

# re: ASP.NET 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.

AddCors and AddMvc has nothing to do with requests. They're simply registering the required services in the IoC container. There might be some other reason for why you should do this, but the one listed is definitely not one :)

-- Kristian

Rick Strahl
September 27, 2016

# re: ASP.NET Core and CORS Gotchas

@Kristian - the middleware *order* definitely matters, although you may be right that it has the important order is in the Configure() method, not ConfigureServices(). To be safe I make sure I have the CORS definition before MVC in both places. Checking now to see which one actually matters, or not at all. Several references mention this explicitly.

Later: Ok - so I checked and you're correct: If you do this in *Configure()*:

app.UseMvc(routes =>
{
      routes.MapRoute(
                 name: "default",
                  template: "{controller=Home}/{action=Index}/{id?}"
      );
});
 
app.UseCors("CorsPolicy");


It doesn't work. It works only if you declare the policy first (or use the policy on the controller).

Thanks for pointing that out - I'll update the post.

Alexander
October 19, 2016

# re: ASP.NET Core and CORS Gotchas

Also works for my SignalR server, thanks!

Datum Geek
December 13, 2016

# re: ASP.NET Core and CORS Gotchas

i was pulling out my hair, going around and around... getting depressed, my beautiful aspnet core webapi - was there no hope??? cors just wouldn't work. no header was returned by the service...

then, FINALLY, i remembered that i once had a problem where an unhandled exception within my webapi method produced the same behavior. this could happen to you. beware of these exceptions whose error masquerades as a missing cors header !!!!!!!!!!!!!!


Jason
January 28, 2017

# re: ASP.NET Core and CORS Gotchas


James
February 25, 2017

# re: ASP.NET Core and CORS Gotchas

This only seems to work for GET requests based on my testing.


Rick Strahl
February 26, 2017

# re: ASP.NET Core and CORS Gotchas

Make sure you add .AddAnyMethod() which is required for it to work with non-GET requests.


Alex
March 06, 2017

# re: ASP.NET Core and CORS Gotchas

That seems to work with Kestrel. But not with IISExpress. Still getting 401.


Daniel U.
March 10, 2017

# re: ASP.NET Core and CORS Gotchas

I followed you implementation. Unfortunality i got Errors like the "URL" is not found in Access-Control-Allow-Origin-Header

I use a JQuery Ajax get request to load an rss feed.

If i use Chrome with Cors extension enabled it works fine. Is it deaktivated or i use another browser i got Errors.

What did i wrong.

Using ASP.net Core with Kestrel


Rick Strahl
March 11, 2017

# re: ASP.NET Core and CORS Gotchas

@Alex - works for me on IIS Express and IIS. There is no reason that the behavior should be any different on a different Web Server because in the end it's just HTTP headers that get injected and the Kestrel is the one doing it regardless of whether IIS Express sits in front of it or not. There must be something else going on. A 401 is not found which I think is different than a CORS error.

@Daniel - What's the exact error message from jquery for this? This really shouldn't be a jquery issue, but a browser issue since the brower's XHR determines the CORS viability.


Ian Buchan
March 15, 2017

# re: ASP.NET Core and CORS Gotchas

I have intermittently ended up on this blog multiple times per month throughout my career in the past 4 years. The advice has always been top notch, covering some of my biggest concerns, with detailed information and quality references.

This post basically covered the exact issue I'm facing with my Angular 2 app hosted through the webpack-dev-server and locally instantiated ASP.NET Core Web API in Kestrel; worked like a charm. Rick Strahl, high five man, you're freaking awesome.


Edgar
April 07, 2017

# re: ASP.NET Core and CORS Gotchas

This is great but I encountered an issue. When I am running from Visual Studio it works(I am sending a request from another server), so I publish the app as an executable and I get -- No 'Access-Control-Allow-Origin' header is present on the requested resource --

I don't understand what I am missing on my release build if everything works while on Visual Studio.


Darren
April 18, 2017

# re: ASP.NET Core and CORS Gotchas

Edgar I am also running into the same issue, works fine locally in visual studio but no'Access-Control-Allow-Origin' header is present on the requested resource -- when on the IIS server


Rick Strahl
April 18, 2017

# re: ASP.NET Core and CORS Gotchas

Are you guys putting the right domains in your CORS headers you are creating?


Christopher Bseirani
April 26, 2017

# re: ASP.NET Core and CORS Gotchas

I was banging my head for two days trying to figure out how to apply CORS to my API...I was following MSDN and it was not working for me - I use your example and it works perfect. THANK YOU!!!


Richard
May 02, 2017

# re: ASP.NET Core and CORS Gotchas

Hi Rick,

I used your blog to get CORS setup with my WebAPI 2.0 app on an IIS server which worked, however; I moved this and the web front end onto an Azure server preventing cookies being sent to the server, which I know is an issue when going cross domains. I have allow any origin, allow any method and allow credentials but the cookie still doesn't get sent. Any ideas of what I might be doing wrong?

Cheers

Rich


Johann Dirry
May 15, 2017

# re: ASP.NET Core and CORS Gotchas

using builder.AllowAnyOrigin() essentially disables CORS. It is preferable to selectively enable domains like builder.WithOrigins("http://example.com")


Rick Strahl
May 15, 2017

# re: ASP.NET Core and CORS Gotchas

@Johann - sure, but many applications need to support open access. If you have an open API that is to be consumed from many clients you need to have any origin.

If you can crank it down - by all means do, but that doesn't invalidate the need for having * accessibility.


Mike
May 16, 2017

# re: ASP.NET Core and CORS Gotchas

As always... you're the man. I can't even count how many times you've helped me out over the past decade or so. If I ever find myself in Hawaii, I shall hunt you down and buy you a coffee/beer/scotch/whatever. Thanks for everything you post.


Amine
June 12, 2017

# re: ASP.NET Core and CORS Gotchas

It works great on Kestrel but not on IIS Express


Rick Strahl
June 12, 2017

# re: ASP.NET Core and CORS Gotchas

@Amine - it should work on either. The CORS settings are made from ASP.NET internally not the Web server, so it shouldn't matter what server you are using. The difference most likely is that you're using a URL that's not cross domain in which case the CORS headers don't get injected into the Response.


Jim
June 24, 2017

# re: ASP.NET Core and CORS Gotchas

Thank you Rick, your article saved me a lot of pain. Just wanted to add that I also needed to add the Access-Control-Allow-Origin header to my global error handler otherwise Angular would spit out an error with message 'Response with status: 0 for URL'. Hope this helps someone.

   app.UseExceptionHandler(appBuilder =>
           {
               appBuilder.Run(async context =>
               {
                   context.Response.Headers.Add("Access-Control-Allow-Origin", "*");   // I needed to add this otherwise in Angular I Would get "Response with status: 0 for URL"
                   context.Response.StatusCode = 500;
                   await context.Response.WriteAsync("Internal Server Error");
               });
           });


Sonam
July 14, 2017

# re: ASP.NET Core and CORS Gotchas

I have created a Web API using ASPNET Core with CORS enabled(hosted on a remote server) just for 1 origin - that is my angular app. That works! The issue is when I try to access my Web API directly from my local machine using Firefox REST Client - it works. Ideally it should not work - my API is not secure. Please suggest how can I avoid the REST Client to get data from my API?


Rick Strahl
July 14, 2017

# re: ASP.NET Core and CORS Gotchas

Did you read the section on watching out for non-cross domain calls? 😃 Same domain requests don't require CORS and the CORS headers are never added by ASP.NET.


Ed Gillett
July 20, 2017

# re: ASP.NET Core and CORS Gotchas

Rick, I think I love you.

Was testing in a browser and in Postman, and of course until I set an origin header matching one of my allowed origins in Postman, nothing was lighting up. Thank you.


Alan
July 31, 2017

# re: ASP.NET Core and CORS Gotchas

...so we're in a spot where we're hitting our Web Application with "quite a few" network requests (for the sake of argument, say 10,000) and we get intermittent {No 'Access-Control-Allow-Origin' header is present on the requested resource...} when currently we have explicitly configured [EnableCors] with wildcard headers on all of our controllers. Refreshing the browser makes the problem disappear until it happens again on a different service.

...Gremlins.


Rick Strahl
August 02, 2017

# re: ASP.NET Core and CORS Gotchas

@Alan - never heard of that, but is it possible there's some sort of caching kicking in? If so you need to make sure you include the CORS headers in the cache differentiation because local requests don't generate the CORS headers which means the wrong thing can get cached.

+++ Rick ---


Eric S
August 04, 2017

# re: ASP.NET Core and CORS Gotchas

Can you show how to get the domains from a data store (say SQL via Entity Framework) and populate the CORS policy with them?


Rick Strahl
August 04, 2017

# re: ASP.NET Core and CORS Gotchas

@Eric, use builder.WithOrigins() and pass a parameterlist of domains.

builder.WithOrigins("http://example.com","http://example2.com");

Alex
August 24, 2017

# re: ASP.NET Core and CORS Gotchas

Cors doesn't work for me anymore in dotnetcore 2.0. Used to work in 1.2


Rick Strahl
August 28, 2017

# re: ASP.NET Core and CORS Gotchas

@Alex - works for me in .NET Core 2. Make sure you're not testing against a local address as CORS will not fire for it. It'll only generate headers for remote access.


James McRay Johnson III
September 17, 2017

# re: ASP.NET Core and CORS Gotchas

Really big help. This blog is one of the best out there for us .NET Core folks.


MusicFromJim
October 26, 2017

# re: ASP.NET Core and CORS Gotchas

It's one thing to know how to do something. It's a totally different thing to be able to help others understand what you know...and without talking down to them. Thanks for your help on a confusing subject. It helped me a lot.


Bitupon
November 21, 2017

# re: ASP.NET Core and CORS Gotchas

Hey Rick, I followed your steps but I am getting the error "Response for preflight has invalid HTTP status code 400" when I try to call an action method from an app hosted on localhost on another port. Can you please throw some light on what I am missing. Thanks.


Joel
November 30, 2017

# re: ASP.NET Core and CORS Gotchas

Thank you for posting this. I kept bumping into the 'Gotchas'. Your post was very helpful.


Herb
December 09, 2017

# re: ASP.NET Core and CORS Gotchas

I have a weird gotcha that I haven't figured out yet. A full description can be found here. https://stackoverflow.com/questions/47731594/why-is-user-identity-isauthenticated-false-when-called-via-cors

CORS is set to enable everything.

What I am trying to do is call Signin via CORS, which would drop an auth cookie. This works, as I see that cookie being dropped. A follow up call to see if I am authenticated returns a FALSE. The call makes it to the server, but the server doesn't think I am authenticated. This doesn't happen when I make the same calls on the same domain.


Andrey
December 20, 2017

# re: ASP.NET Core and CORS Gotchas

Hi!

Thanks for the article. I don't want to enable CORS in my web application, so I did not configured it. The issue is that now my web app throws 404 response code for OPTIONS requests, which creates noise in the application logs. Is it possible to configure CORS middleware to return 200 for OPTIONS requests while not allowing cross domain requests into my api?


yyannekk
December 27, 2017

# re: ASP.NET Core and CORS Gotchas

[Rick] : works for me in .NET Core 2. Make sure you're not testing against a local address as CORS will not fire for it. It'll only generate headers for remote access.

@Rick do you know why this is so and where this is documented? I ran into problems here when I tested my CORS setup with Postman. Headers were not generated, so I thought my setup is wrong. Turns out I just needed to execute requests from my dev frontend running in a webserver and it works.

Took me some time though. So why do they do that, and where is that behaviour documented?


Rick Strahl
December 29, 2017

# re: ASP.NET Core and CORS Gotchas

@yyannekk - It works that way because local access doesn't require CORS - there's no need to send the headers and add that overhead to requests. To test with Postman you can add an Origin header and force CORS to fire.


Rick Strahl
December 29, 2017

# re: ASP.NET Core and CORS Gotchas

@Herb - make sure you enable auth headers to be passed through in CORS with .AllowCredentials(). If you miss that credentials may end up not getting passed through with each request. This affects Cookie and Authorization HTTP headers.


Eddy
January 05, 2018

# re: ASP.NET Core and CORS Gotchas

Hi,

Great post, how would like do to add origins at runtime without if you have two different application, one is the API and the other the website?

Thank you...


MV10
January 14, 2018

# re: ASP.NET Core and CORS Gotchas

Got a laugh out of the "king with no clothes" jab. W3C should be ashamed of itself. I keep wondering what it's going to take for the industry to collectively agree to ditch this CORS pseudo-security nonsense. Then I remember it took about 15 years for REST to gain popularity (and even now it mostly isn't done correctly), and I lose hope...


P BHARATH KUMAR
March 06, 2018

# re: ASP.NET Core and CORS Gotchas

I created asp.net core 2.0 Application with windows authentication. I created angular5 application separately when i am calling angular post method with Core i am getting Cors Error. I used Cors section as well but it is not working.


Richard
May 14, 2018

# re: ASP.NET Core and CORS Gotchas

Thank You, Thank You, Thank You for this. I got my "CorsPolicy" working for a Get. Then I added a Post method and it didn't work. This article helped me resolve the issue so Thank You!!!!


Wessel Fick
May 29, 2018

# re: ASP.NET Core and CORS Gotchas

Thank you for this, I got CORS to work correctly now but i have one last issue left where if you have a public API MVC controller methods that require no CORS checking. I used the following process as per MS doc examples on my action method

[DisableCors]
[HttpGet("CORSTEST2")]
public string CORSTEST2()
{
   return "CORS TEST 2 RESULT";
}

MS logs report the following error on my request

info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3] Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Cors.Internal.DisableCorsAuthorizationFilter'.

Any idea what i'm doing wrong here ?


Mike Ritchie
July 05, 2018

# re: ASP.NET Core and CORS Gotchas

I have an open API was working fine with the CORS configuration (see code below). I worked on a local server on localhost (of course), by IP address to my local IIS from another domain in my office, and in a test server in Azure. I changed nothing in CORS and deployed a new release to Azure. Now Azure gives me the following error when making cross domain calls to the API.

Are you aware of any recent changes in Azure that affect CORS? Where else should I look to troubleshoot this problem?

.Net Core 2.1

ERROR when accessing server in Azure.

angular.js:12759 Cross-Origin Read Blocking (CORB) blocked cross-origin response http://wecongobackofficetest.azurewebsites.net/api/AccountApi/Michael@GerminalResources.com with MIME type text/html. See https://www.chromestatus.com/feature/5629709824032768 for more details. 

Code from my StartUp.cs file

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

 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            // global policy - assign here or on each controller
            app.UseCors("CorsPolicy");
            
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseBrowserLink();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }


James MacIvor
November 05, 2018

# re: ASP.NET Core and CORS Gotchas

Just a note for anyone who's having a rough time on an Azure deployment and somehow reads down this far. If you configure CORS in Azure via the portal then it will override your code CORS policies. This means that if you are using .WithCredentials and .AllowAnyHeader and etc then all of that will inexplicably stop working. Once you remove the Azure configuration then it will work normally.

You should add your any string values (like origin) as an AppSetting, but let ASP .NET Core (and not Azure) handle the CORS implementation.


Marcel
November 17, 2018

# re: ASP.NET Core and CORS Gotchas

Dear Rick, Thank you for your enlightening post. I am struggling with the ‘withOrigins’ functionality of the builder. I managed to add multiple domains hard coded by separating them (see code below), but I would like to set those domains dynamically (from a json-file or from a database). Is that possible?

options.AddPolicy("CorsPolicy",
    builder => builder.WithOrigins("http://www.domain1.com","http://www.domain2.com")
    .AllowAnyMethod()
    .AllowAnyHeader()
    .AllowCredentials());

granadaCoder
December 07, 2018

# re: ASP.NET Core and CORS Gotchas

Thanks! Great article. And I just went and created a const to avoid the snapfu you hit.

public const string CustomCorsPolicyName = "CustomCorsPolicyName";


Rajendra Mahajan
January 11, 2019

# re: ASP.NET Core and CORS Gotchas

How can I use string of origins from appsettings.json file? I tried to save it as "," separated and split as array of string parameters is an array of strings. builder.WithOrigins(parameters);


wgrs
April 04, 2019

# re: ASP.NET Core and CORS Gotchas

I have just started testing a Vue app against a aspnet core api and have implemented CORS as show in the example above. GET requests work fine but POST requests throw the CORS error. I did a bit of digging and it seems a possible reason is the "preflight" ORIGINS request sent before a POST request. Although my CORS config has AllowMethods("*"), this apparently does not entertain OPTIONS requests. I have checked the network inspector and the last request before the POST fails is the OPTIONS request, so I'm guessing that is the cause. Now I need to find a way to allow these preflight requests to be serviced.


Mark Entingh
April 15, 2019

# re: ASP.NET Core and CORS Gotchas

I am also having issues with CORS because Chrome sends a pre-flight request using Content-Type:OPTIONS and ASP.NET Core is returning an empty 204 response, which triggers the CORB error.


John Dover
May 10, 2019

# re: ASP.NET Core and CORS Gotchas

Rick I have always enjoyed reading your articles! I like how you are able to take a 'specific' topic and make it easy to understand. With that being said, I have issues with CORS and windows authentication. I recently started developing using Vue.js as my client using axios for requests to api. Following your example above I am still not able to hit my api method from my client. Here is a snippet from client calling api. I have tried to include 'withCredentials', or not including any headers at all, but nothing seems to work

      this.$http.get("http://localhost:58460/api/values", {
          
      headers: {
         //'Content-type': 'application/json',
           'withCredentials': true
         //'Bearer': ' ' + this.token
      }})
      .then(response => this.currentUser = response.data)
      .catch(err => console.log(err));

and in my Values controller

    [Route("api/Values")]
    [ApiController]
    //[EnableCors("CorsPolicy")]
    public class ValuesController : ControllerBase
    {
        // GET api/values
        [HttpGet]
        [Authorize (AuthenticationSchemes = "Windows")]
        public ActionResult<string> Get()
        {
            return this.HttpContext.User.Identity.Name;
        }
    }

and lastly my Startup.cs

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy",
                builder =>
                {
                    builder
                    //.WithOrigins("http://localhost:8081", "https://localhost:8081")
                    .AllowAnyOrigin()
                                        .AllowAnyHeader()
                                        .AllowCredentials()
                                        .AllowAnyMethod();
                });
            });
            services.AddAuthentication(IISDefaults.AuthenticationScheme);
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }
            app.UseCors("CorsPolicy");
            app.UseHttpsRedirection();
            app.UseMvc();
        }

with this in place I still receive a 401 unauthorized when trying to access my api. Do you have any suggestions on how to make this work? I have been struggling with this for 2 days now, and at my wits end. Any help is appreciated. I know that this is not SO, but thought your experience might help. Thanks!


Rick Strahl
May 11, 2019

# re: ASP.NET Core and CORS Gotchas

I think the API changed recently and you now need to use SetIsOriginAllowed(). I seem to recall recently that AllowAnyOrigin() no longer worked.

services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy",
                    builder => builder
                            // required if AllowCredentials is set also
                        .SetIsOriginAllowed(s=> true)
                        //.AllowAnyOrigin()             
                        .AllowAnyMethod()
                        .AllowAnyHeader()                            
                        .AllowCredentials()
                    );
            });

TehWardy
July 11, 2019

# re: ASP.NET Core and CORS Gotchas

Is It me or is CORS the most pointless piece of technology ever.

I mean ... any source can claim it's making a request from a given source domain and nothing in the CORS architecture requires any form of identification beyond "ok you gave me a header saying you are calling from x domain".

The whole CORS concept needs throwing out IMO, if services want to protect their endpoints preventing calls from only but a select few why not use pre-shared keys or something, that sort of mechanism already works for things like FTP clients so why not HTTP clients?


Rick Strahl
July 13, 2019

# re: ASP.NET Core and CORS Gotchas

@TehWardy - As a protection strategy from malicious sites it's worthless. It only provides value to the host site from protecting itself and the client code from accessing resources it's not supposed to. It's a very limited security feature and I agree - it's mostly worthless in that it gives people who don't understand what it actually does a false sense of security that's not actually there.


VICTOR J ESPINA
August 10, 2019

# re: ASP.NET Core and CORS Gotchas

I've been suffering from this problem for a few days now. I've tried everything until I found this and other paper indicating the need to use the [EnableCors] annotation on the controller. Before doing that, I was still receiving the CORS error despite all my efforts. Thanks a lot.


PA
August 22, 2019

# re: ASP.NET Core and CORS Gotchas

Hi,

We have following in our code and it was working fine when testing locally. But now we have added a new field in header which is resulting in error 'Access to XMLHttpRequest at from origin 'http://localhost:8181' has been blocked by CORS policy: Request header field is not allowed by Access-Control-Allow-Headers in preflight response.'

                allowedDomains = new[] { "http://localhost:4200", "http://localhost:3000", "http://localhost:4000", "http://localhost:8181" };

                options.AddPolicy("CorsPolicy",
                builder => builder
                .WithOrigins(allowedDomains)
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials());

Any idea what may need to change now?


Dries
August 29, 2019

# re: ASP.NET Core and CORS Gotchas

A bit late in the game but I want to leave my experience with CORS and .Net Core in combination with IIS/IIS Express.

So the behaviour I got was that the OPTIONS call performed by Firefox (in my case) returned without any Access-Control-* headers. And thus the browser rejected to perform the CORS request. I'm running .net Core (3.0 preview8) on an IIS Express instance with windows authentication.

The thing is that when you enable windows authentication in your IIS setup any options call get bounced because the browser (in my case Firefox) does not add the authentication header to the request.

The quickest way to get this to work is to allow anonymous access to your site. Or setup IIS to accept anonymous calls when the OPTION verb is used


Peter Kellner
November 03, 2019

# re: ASP.NET Core and CORS Gotchas

As always, finding your notes here helps. Might be helpful to update article with current core 3 cors setup (assuming that also works with previous versions of core). Thanks


Rick Strahl
November 03, 2019

# re: ASP.NET Core and CORS Gotchas

@Peter - nothing has changed with this in Core 3.0 except there are a few additional methods on the configuration builder that allow more granular configuration.


David
November 05, 2019

# re: ASP.NET Core and CORS Gotchas

Just wanted to comment on the usefulness of CORS. I understand why people feel frustrated when stumbling across it. Reading the specifications can make the whole design appear useless.

What we're really talking about with CORS is the same-origin policy. It's a client-side constraint. It protects innocent users from making requests to sites they don't intend to visit. CORS relaxes this restriction.

An example would be an XSS attack on a popular forum, say AcmeNerds. A hacker could post a comment to AcmeNerds that contains AJAX to call another site named UnfortunateVictim. As they browse AcmeNerds, users would be making many requests to UnfortunateVictim without even knowing, resulting in a DDOS attack whose source would be hard for admins of UnfortunateVictim to even track down the source. This type of attack is stopped by default in the browser by the same-origin restriction.

This also affects requests made using the user's browser, i.e. CSRF. When you set '*' as the allowed resource, you're telling all users that "yes, you can talk to me from any website including ones I DON'T administrate," which in fact is not secure at all.

Just extrapolate on the ever-growing compromised sites and their effect on unwittingly compromised users, and it should make sense that CORS will only become more important, not less, in the future.


Lex Li
March 23, 2020

# re: ASP.NET Core and CORS Gotchas

I doubt whoever reported issues with IIS/IIS Express has enabled Windows authentication, which blocks anonoymous preflight requests.

For IIS the out-of-band CORS module can ease the pains, but for IIS Express Microsoft didn't have an installer. So I wrote a few PowerShell scripts to help https://github.com/lextm/iisexpress-cors


Sushmitha
May 04, 2020

# re: ASP.NET Core and CORS Gotchas

Hi Rick,

Thanks for this very useful post. But I am still facing issues with cors. I am using .net core 2.1 for my backend api with windows authentication enabled and angular 8 on the front end. I have set up cors in the startup.cs as the same way you have done, except, I have given a specific origin. Whenever I make a get request, it works fine. But when it come to post, "Access to XMLHttpRequest at 'https://localhost:4321//api/Project/PostProject' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource." error comes up. Any suggestion would be great help.


Aravind
May 07, 2020

# re: ASP.NET Core and CORS Gotchas

@Lex Li - you are correct. I have experienced this. This CORS issue will crop up from any app like Angular in my case. Even though, we configure our code to EnableCors and assuming to have AllowAnyOrigin() as the api must be accepting any, i am still fighting to determine a possible working solution.

I only have one option at the moment to make it work.

  1. Enable anonymous auth also (either with or without Windows auth)

I tried all the other solutions, mix and match with the configurations in the .net core web api, by removing the SetIsOriginAllowed(), AllowAnyOrigin(), setting the WithOrigin([]) and nothing so far works. This is the situation with

  • IIS Express (local api running with swagger and accessible although: running at localhost:15520)
  • Angular (calling from angular is giving me the cors policy err- running at localhost:4200)
  • Enabled only Windows authentication on my .net core web api
  • AllowedHosts in the appsettings.json : tried with default "*" or "localhost"

Any solutions or suggestions?


Santosh
June 13, 2020

# re: ASP.NET Core and CORS Gotchas

Hi I am facing the same problem as Sushmita above when calling my Asp.net Core WebAPI from Angular app for put/post request with GEt requests working.

I need windows authentication with specific origins allowed and the only way to get it working is enabling Anonymous authentication in launchSettings.json as well !


Brian
December 31, 2020

# re: ASP.NET Core and CORS Gotchas

For anyone struggling with the pre-flight CORS error not working, I found the answer on another blog. Set it to allow any headers (and any methods if you wish).

services.AddCors(options =>
  {options.AddPolicy(name: MyAllowSpecificOrigins,
  builder =>
  {
    builder.WithOrigins("http://localhost:3000")
    .AllowAnyHeader()
    .AllowAnyMethod();
  });
});

The site is here: https://www.cognizantsoftvision.com/blog/cross-origin-resource-sharing-and-asp-net-core-3-1/


Rick Strahl
December 31, 2020

# re: ASP.NET Core and CORS Gotchas

@Brian - Uh, the very first example in this post does just that?


Marc Schluper
February 03, 2021

# re: ASP.NET Core and CORS Gotchas

It's amazing how many gotchas there are getting CORS to work with .NET. This has been the case like forever - just check StackOverflow. Thousands of people struggling. It is as if nobody at Microsoft ever thought this through. Even the need for the CORS Module and the need to configure IIS were not documented for .NET Core 3 until recently, and only after people outside of Microsoft pointed it out.

Now check how many people are struggling to configure CORS in nodejs. Hardly anyone. It can be done in five minutes, including a whitelist. Amazing.


Bruce
February 15, 2021

# re: ASP.NET Core and CORS Gotchas

This had me stumped, I was missing SetIsOriginAllowed:

.SetIsOriginAllowed(s=> true)

Once again Rick's blog pulls my *** out of the fire, thanks Rick!


Sreekumar P Nair
June 19, 2021

# re: ASP.NET Core and CORS Gotchas

Hi Rick,

Thanks for this very useful post. But I am still facing issues with cors. I am using .net core 3.1 for my backend API with JWT authentication. The problem is , After enabling CORS, the session is not working for the request originated from my Angular application which hosted on a different port. Could you please guide me in implementing the Session along with CORS?

Regards Sree


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024