ASP.NET Core and CORS Gotchas

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
Other Posts you might also like
- Map Physical Paths with an HttpContext.MapPath() Extension Method in ASP.NET
- Getting the Client IP Address in ASP.NET Core
- Getting the ASP.NET Core Server Hosting Urls at Startup and in Requests
- Fighting through Setting up Microsoft Trusted Signing
- Resolving Paths To Server Relative Paths in .NET Code
The Voices of Reason
# re: ASP.NET Core and CORS Gotchas
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
# re: ASP.NET Core and CORS Gotchas
# re: ASP.NET Core and CORS Gotchas
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
# re: ASP.NET Core and CORS Gotchas
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.
# re: ASP.NET Core and CORS Gotchas
# 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 !!!!!!!!!!!!!!
# re: ASP.NET Core and CORS Gotchas
Thanks for this, credited it for my answer at stackoverflow. http://stackoverflow.com/questions/41796468/failed-http-post-with-angular2-to-asp-net-core-api/41815277#41815277
# re: ASP.NET Core and CORS Gotchas
This only seems to work for GET requests based on my testing.
# re: ASP.NET Core and CORS Gotchas
Make sure you add .AddAnyMethod() which is required for it to work with non-GET requests.
# re: ASP.NET Core and CORS Gotchas
That seems to work with Kestrel. But not with IISExpress. Still getting 401.
# 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
# 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.
# 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.
# 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.
# 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
# re: ASP.NET Core and CORS Gotchas
Are you guys putting the right domains in your CORS headers you are creating?
# 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!!!
# 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
# 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")
# 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.
# 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.
# re: ASP.NET Core and CORS Gotchas
It works great on Kestrel but not on IIS Express
# 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.
# 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");
});
});
# 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?
# 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.
# 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.
# 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.
# 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 ---
# 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?
# 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");
# re: ASP.NET Core and CORS Gotchas
Cors doesn't work for me anymore in dotnetcore 2.0. Used to work in 1.2
# 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.
# re: ASP.NET Core and CORS Gotchas
Really big help. This blog is one of the best out there for us .NET Core folks.
# 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.
# 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.
# re: ASP.NET Core and CORS Gotchas
Thank you for posting this. I kept bumping into the 'Gotchas'. Your post was very helpful.
# 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.
# 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?
# 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?
# 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.
# 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.
# 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...
# 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...
# 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.
# 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!!!!
# 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 ?
# 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");
}
# 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.
# 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());
# 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";
# 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);
# 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.
# 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.
# 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!
# 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()
);
});
# 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?
# 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.
# 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.
# 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?
# 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
# 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
# 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.
# 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.
# 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
# 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.
# 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.
- 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?
# 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 !
# 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/
# re: ASP.NET Core and CORS Gotchas
@Brian - Uh, the very first example in this post does just that?
# 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.
# 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!
# 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
# re: ASP.NET Core and CORS Gotchas
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