.NET Core UseCors() does not add headers - c#

This would be a duplicate of How does Access-Control-Allow-Origin header work?, but the method there also isn't working for me. I'm hoping I'm just missing something.
I am trying to get a Access-Control-Allow-Origin header in my response from my .NET Core Web API, which I am accessing via AJAX.
I have tried several things. All, unless noted otherwise, have been in the Startup.cs file.
Method 1
As per the Microsoft Documentation:
public void ConfigureServices(IServiceCollection services)
{
// Add database
services.AddDbContext<DbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DbConnection")));
// Add the ability to use the API with JSON
services.AddCors();
// Add framework services.
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
serviceScope.ServiceProvider.GetService<DbContext>().Database.Migrate();
serviceScope.ServiceProvider.GetService<DbContext>().EnsureSeedData();
}
}
app.UseCors(builder => builder.WithOrigins("https://localhost:44306").AllowAnyMethod());
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
Authority = Configuration["Authentication:AzureAd:AADInstance"] + Configuration["Authentication:AzureAd:TenantId"],
Audience = Configuration["Authentication:AzureAd:Audience"],
});
app.UseMvc();
}
Method 2
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddCors(options => options.AddPolicy("AllowWebApp",
builder => builder.AllowAnyMethod()
.AllowAnyMethod()
.AllowAnyOrigin()));
//.WithOrigins("https://localhost:44306")));
// ...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// ...
app.UseCors("AllowWebApp");
// ...
}
I've also tried adding [EnableCors("AllowWebApp")] on both the Controller and Method.
From Postman, I get:
content-encoding → gzip
content-type → text/plain; charset=utf-8
date → Wed, 25 Jan 2017 04:51:48 GMT
server →Kestrel
status → 200
vary → Accept-Encoding
x-powered-by → ASP.NET
x-sourcefiles → =?UTF-8?B?[REDACTED]
I've also tried it in Chrome, and gotten similar headers.
If it matters, the method I'm trying to access has an Authorize attribute on it. But that part should be working fine (I'm at least getting a good response)
So, am I missing something very obvious, or did this get broken? I'm currently running version 1.1.0.
Edit adding JS and Controller Stub
function getContactPreviews(resultsCallback) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = () => {
if (xmlhttp.readyState == XMLHttpRequest.DONE && xmlhttp.status == 200) {
resultsCallback(JSON.parse(xmlhttp.response));
}
}
xmlhttp.open("GET", "https://localhost:44357/api/User/ContactsPreview", true);
xmlhttp.setRequestHeader("Authorization", "Bearer " + localStorage.getItem("AuthorizationToken"));
xmlhttp.send();
}
Controller Stub
[Authorize]
[Route("api/[controller]")]
public class UserController : ApiController
{
[HttpGet(nameof(ContactsPreview))]
[EnableCors("AllowWebApp")]
public IEnumerable<Customer> ContactsPreview()
{
// ...
}
}

The problem is that when using Bearer authentication (or any I would imagine), it adds a header "Authorization", and the server will only give an okay if the setup allows for that header.
There's two ways to solve the problem, and below is the only code needed. It goes in the Configure() method in Startup.cs in the Web API solution.
Method 1: Allow all headers
app.UseCors(builder => builder.WithOrigins("https://localhost:44306")
.AllowAnyMethod()
.AllowAnyHeader());
Method 2: Allow specific headers
app.UseCors(builder => builder.WithOrigins("https://localhost:44306")
.AllowAnyMethod()
.WithHeaders("authorization", "accept", "content-type", "origin"));
The extra headers are because, per the documentation:
Browsers are not entirely consistent in how they set Access-Control-Request-Headers. If you set headers to anything other than "*", you should include at least "accept", "content-type", and "origin", plus any custom headers that you want to support.

The Access-Control-Allow-Origin header is returned only if:
The request includes an "Origin" header.
The requested origin matches the CORS policy.
Then the server returns the ACAO-header with the origin URL as value.
The Origin header is usually set by the XMLHttpRequest object.
For more information, see How CORS works

In Startup.cs file, add following
public CorsPolicy GenerateCorsPolicy(){
var corsBuilder = new CorsPolicyBuilder();
corsBuilder.AllowAnyHeader();
corsBuilder.AllowAnyMethod();
corsBuilder.AllowAnyOrigin(); // For anyone access.
//corsBuilder.WithOrigins("http://localhost:56573"); // for a specific url. Don't add a forward slash on the end!
corsBuilder.AllowCredentials();
return corsBuilder.Build();
}
In ConfigureServices method:
services.AddCors(options =>
{
options.AddPolicy("AllowAllOrigins", GenerateCorsPolicy());
});
// To Apply CORS globally throughout the application
// In Configure method, add
app.UseCors("AllowAllOrigins");
[DisableCors]
Using DisableCors attribute, we can disable CORS for a controller or an action.
//To Enable CORS controller basis - If you apply globally you don't need this one.
[EnableCors("AllowAllOrigins")]
public class HomeController: Controller {}

In Startup.cs at the end of ConfigureServices() add this:
services.AddCors();
Then in Configure() at the top add this:
app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().WithExposedHeaders("*"));
// alternatively you could use .With... methods to specify your restrictions:
// app.UseCors(x => x.WithOrigins("http://domain1.com").WithMethods("GET","POST").WithHeaders("Authorization").WithExposedHeaders("*"));

As of date 03/17/2019, .NET Core version 2.1:
This will possibly save some time to other poor souls...at some point I started to be frustrated and almost gave up on .NET Core WebApi as a separate project.
In real life circumstances, there are other configurations in Startup functions e.g. I had Swagger, DI registrations etc. I wasn't able to make bloody thing work until I put both AddCors() and UseCors() methods to be the first one getting called in configuration functions.
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("SomePolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors("SomePolicy");
After that, calls from Angular 6 app (Swagger Typescript client calls) started to work as a charm.

I wasted hours on this problem today, only to discover it's because .Net Core 3 doesn't support preflight OPTIONS requests if you use the Endpoint routing RequirePolicy method of enabling CORS!
The official documentation does mention this, but it wasn't called out in an obvious warning block so I'd totally missed it.
The following will fix the problem, but it'll apply a global CORS policy, so caveat emptor!
Service Configuration:
public void ConfigureServices(IServiceCollection services)
{
string[] corsOrigins = Configuration.GetSection("AllowedHosts").Get<string[]>();
services.AddCors(options =>
{
options.AddPolicy("AllowConfiguredOrigins", builder => builder
.WithOrigins(corsOrigins)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
);
});
...
Basically, don't do this:
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseCors();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers().RequireCors("AllowConfiguredOrigins");
});
...
...do this instead
Configure()
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseCors("AllowConfiguredOrigins");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
...

I want to add one more possibility for those who may have followed the advice above and it is still not working. In my case I was not getting the header returned (or only getting it on the first request) because of the order of registration in the pipeline.
I changed the order from this:
app.UseResponseCaching();
app.UseHttpsRedirection();
app.UseCors("WideOpen");
app.UseMvc();
To this:
app.UseCors("WideOpen");
app.UseResponseCaching();
app.UseHttpsRedirection();
app.UseMvc();
That resolved my issue.

Related

No service for type ' Microsoft.AspNetCore.Components.WebAssembly.Authentication.BaseAddressAuthorizationMessageHandler' Error

I am currently working on a project that consists of sub-projects such as WebApp, API, and Client class library. (The project structure is shown below).
Project Solution Structure
Although the project is a web-based project, it uses windows Identity as authentication identity since it is an internal application. I implemented the authorization policy of the WebApp project without any problems by following the steps in the implementation_link.
Now I can control access using DataAnnotation in WebApp (ex. [Authorize(Roles = "Admin"]). If I add Authorization control on the API side, WebApp cannot access this API. This is because of HttpContext.User is null. I found the solution to this problem solution_link. I adapted this solution to the project as below:
ServiceCollectionExtensions.cs in WebApp project:
public static IServiceCollection AddAuraServices(this IServiceCollection serviceCollection, IConfiguration configuration)
{
serviceCollection.AddTransient<IModelDatabaseNamesProvider, StandardCasingModelDatabasesNamesProvider>();
serviceCollection.Configure<RouteOptions>(routeOptions =>
{
routeOptions.ConstraintMap.Add(ModelDatabasesNameConstraint.Name, typeof(ModelDatabasesNameConstraint));
});
serviceCollection.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
serviceCollection.AddScoped<IModelMetadataProvider>(serviceProvider =>
{
var httpContext = serviceProvider.GetRequiredService<IHttpContextAccessor>().HttpContext;
var modelName = httpContext.Request.RouteValues["model-name"].ToString();
return new ModelMetadataProvider(modelName);
});
DateOnlyTypeConverter.AddAttributeToType();
serviceCollection.AddHttpClient<UploadRulesClient>("ServerAPI", (httpClient) =>
{
httpClient.BaseAddress = new Uri(configuration["AuraApiClient:BaseAddress"]);
}).AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
serviceCollection.AddHttpClient<ScenarioZipFilesClient>("ServerAPI",(httpClient) =>
{
httpClient.BaseAddress = new Uri(configuration["AuraApiClient:BaseAddress"]);
}).AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
serviceCollection.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
.CreateClient("ServerAPI"));
var jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
ClientJsonResponse.Configure(jsonSerializerOptions);
serviceCollection.AddSingleton(jsonSerializerOptions);
serviceCollection.AddAuraDropzoneConfig(configuration);
return serviceCollection;
}
Startup.cs of WebApp:
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.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
services.AddAuthorization();
services.AddControllersWithViews();
//services.AddRazorPages();
services.AddAuraServices(Configuration);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/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: "model-database", pattern: "{model-name:modeldatabasename}/{controller=ZipFiles}/{action=Index}/{id?}");
endpoints.MapControllerRoute(name: "default", pattern: "", new { controller = "Home", action = "Index" });
//endpoints.MapRazorPages();
});
}
}
But this time I am getting No service for Type Error. How can I solve this problem? Where do you think I am going wrong? Thanks
Edit:
As you can see BaseAddressAuthorizationMessageHandler is in namespace Microsoft.AspNetCore.Components.WebAssembly.Authentication. It is supposed to be used with Blazor WebAssembly apps and it attaches the access token to the authentication header of HttpClient requests. BaseAddressAuthorizationMessageHandler depends on other services like IAccessTokenProvider which is responsible to return the access token. For example in web assembly IAccessTokenProvider default implementation retrieves the access token from browser session storage.
If you want to attach access tokens to your http requests your should probably implement your own DelegatingHandler instead of BaseAddressAuthorizationMessageHandler.
Old answer:
You have to register BaseAddressAuthorizationMessageHandler:
serviceCollection.AddTransient<BaseAddressAuthorizationMessageHandler>();

Asp.net Core 3.0 CORS not working based on official documentation

I want to enable CORS with Asp.Net Core 3.0 API project. This is the basic generated Asp.Net Core Api template. Everything is default from the template, except I added CORS settings from the documentation: Enable Cross-Origin Requests (CORS) in ASP.NET Core
Here it is my Startup.cs
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.AddControllers();
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.WithOrigins("localhost", "www.google.com")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors("CorsPolicy");
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
And these are my response headers:
What should I set up for getting corret CORS headers in Response?
Here it is my fetch api test:
Oops, I successed to solve this.
This combination was the only one to me, what is working:
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.AddControllers();
services.AddCors(); //This needs to let it default
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors(
options => options.SetIsOriginAllowed(x => _ = true).AllowAnyMethod().AllowAnyHeader().AllowCredentials()
); //This needs to set everything allowed
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
If you put the API URL directly in the browser, CORS is not involved.
It isn't a cross-origin request.
That only happens when you have a page hosted at one origin, e.g. localhost:5000, which has JavaScript code that calls an API at origin localhost:5001.
(or otherwise fetches resources from another origin)
But in your case the only origin is the API origin and thus CORS is not needed.

CORS Headers missing from basic API response apnetnet core 3.0

I have just created a default dotnet core 3.0 API project with the basic weather forecast API. I wanted to get CORS working before I did anything else with the project.
In startup i have the following code....
private readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddControllers();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(MyAllowSpecificOrigins);
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
As you can see, I am not doing anything special or seemingly incorrect. This is directly from the MSDN documentation....
https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.0
The problem is that when sending requests through both the browser and postman, There are none of the expected headers in the given responses.
I have googled the crap out of this and have not got anywhere. Am i missing something? could it be environmental? has it changed from a previous version of core?

CORS in .NET Core

I am trying to enable CORS in .NET Core in this way:
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()));
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseCors("AllowAll");
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
However, when I am sending a request to my app with Angular 2 I am getting the famous
"No 'Access-Control-Allow-Origin' header is present on the requested
resource."
error message.
I am also using Windows Authentication + WebListener.
If I am checking with postman the only response headers are:
Content-Length →3533
Content-Type →application/json;
charset=utf-8
Date →Fri, 14 Oct 2016 12:17:57
GMT Server →Microsoft-HTTPAPI/2.0
So there must be still something wrong configured. Any proposals?
If I remove the outcommented line it works, but I need Windows Authentication :-(
var host = new WebHostBuilder()
.UseWebListener()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
//.UseWebListener(options => options.Listener.AuthenticationManager.AuthenticationSchemes = AuthenticationSchemes.NTLM)
.Build();
Assume you have the answer, but for the benefit of searchers, I had the same problem with the standard tutorial on .NET Core Cors.
One of the many errors encountered:
XMLHttpRequest cannot load localhost:64633/api/blogs. Response
to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'localhost:56573' is therefore not allowed
access. The response had HTTP status code 500.
After playing around, the following code worked. Full class posted below to aid understanding of what goes where.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Cors.Infrastructure;
namespace NetCoreWebApiTesting
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
if (env.IsEnvironment("Development"))
{
// This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
builder.AddApplicationInsightsSettings(developerMode: true);
}
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore);
// ********************
// Setup CORS
// ********************
var corsBuilder = new CorsPolicyBuilder();
corsBuilder.AllowAnyHeader();
corsBuilder.AllowAnyMethod();
corsBuilder.AllowAnyOrigin(); // For anyone access.
//corsBuilder.WithOrigins("http://localhost:56573"); // for a specific url. Don't add a forward slash on the end!
corsBuilder.AllowCredentials();
services.AddCors(options =>
{
options.AddPolicy("SiteCorsPolicy", corsBuilder.Build());
});
}
// 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();
app.UseApplicationInsightsRequestTelemetry();
app.UseApplicationInsightsExceptionTelemetry();
app.UseMvc();
// ********************
// USE CORS - might not be required.
// ********************
app.UseCors("SiteCorsPolicy");
}
}
}
To use it you can add the EnableCorsAttribute either on the controller or on the method. e.g.
[EnableCors("SiteCorsPolicy")]
[Route("api/[controller]")]
public class BlogsController : Controller
{
}
or
// POST api/value
[EnableCors("SiteCorsPolicy")]
[HttpPost]
public HttpResponseMessage Post([FromBody]Blog value)
{
// Do something with the blog here....
var msg = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
return msg;
}
When I called this using the following code (using standard js/jQuery for easy of copy and paste), the communication stopped being rejected.
function HandleClick() {
var entityData = {
"blogId": 2,
"url": "http://blog.com/blog1",
"posts": [
{
"postId": 3,
"title": "Post 1-1",
"content": "This is post 1 for blog 1",
"blogId": 2
},
{
"postId": 4,
"title": "Post 1-2",
"content": "This is post 2 for blog 1",
"blogId": 2
}
]
};
$.ajax({
type: "POST",
url: "http://localhost:64633/api/blogs",
async: true,
cache: false,
crossDomain: true,
data: JSON.stringify(entityData),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (responseData, textStatus, jqXHR) {
var value = responseData;
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}
});
}
This way works normally, just tried it on angular2 with .net core.
The issue the OP is having is that this doesnt work with windows authentication. I am assuming the middleware for windows authentication is happening before a request comes through, in which case its breaking. Best bet would be to see if there is a way to enable the windows auth middleware after the cors middleware has processed in Configure.
Then the order would be
App.UseCors()
App.UseWindowsAuth()
App.UseMVC()
They must happen in this order for it to work.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()));
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseCors("AllowAll");
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
What the documentation misses, is the importance of .AllowAnyMethod(). If not present, the dreaded No 'Access-Control-Allow-Origin' will keep bugging you. In your code it's there, so I guess you missed setting the right header in jour client side application.
I Personally got it to work by allowing all:
app.UseCors(b => b.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials());
And my Angular post function like:
post(model) {
let headers = new Headers({
'Content-Type':'application/json; charset=utf-8;'
,'Accept':'*/*'
});
let options = new RequestOptions({ headers: headers });
let body = JSON.stringify(model);
return this.http.post(
'http://localhost:58847/api/TestPost', body, options)
.map((response: Response) => {
let res = response.json();
return res;
}
);
}
After that, you gradually work your way up by specifying origins etc.
In ASPNET CORE 2.0, The following works for me
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new CorsAuthorizationFilterFactory("AllowSpecificOrigin"));
});
services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigin",
builder => builder.WithOrigins("http://localhost:5000").AllowAnyHeader()
.AllowAnyMethod());
});
services.AddMvc()
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
loggerFactory.AddConsole();
loggerFactory.AddDebug(LogLevel.Information);
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Shows UseCors with named policy.
app.UseCors("AllowSpecificOrigin");
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
}
}
Add this section in appsettings.json
"App": {
"CorsOrigins": "http://yourdomain"
}
and
services.AddCors(options => {
options.AddPolicy(DefaultCorsPolicyName, builder => {
builder.WithOrigins(
_appConfiguration["App:CorsOrigins"]
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.RemovePostFix("/"))
.ToArray()
).SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
Note: App:CorsOrigins in appsettings.json can contain more than one address with splitted by comma.
You just need to add this in ConfigureService Method of StartUp Class
services.AddCors ();
and this in Configure Method of Startup Class and it will work fine then
app.UseCors (builder => builder
.AllowAnyOrigin ()
.AllowAnyHeader ()
.AllowAnyMethod ());
There is nothing more to add to enable CORS in .Net Core
I just fixed my problem with Cors in Core 3.1. I was following almost every example and documentation out there. Unfortunately nothing worked until I did .Build() for the builder inside the AddPolicy portion.
services.AddCors(options => {
options.AddPolicy(
name: OrginPolicyKey,
builder => builder.WithOrigins("http://localhost:3000")
.AllowAnyHeader()
.AllowAnyMethod()
.Build() // <--- This right here
);
});
Also, other people were mentioning about calling the UseCors(OrginPolicyKey) before the rest of your routing and UseMvc stuff. That is correct and I saw that Putting UseCors after the route part broke it. Below is how mine is setup.
app.UseCors(OrginPolicyKey); // <--- First
// Then routing stuff..
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints
.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}"
);
});
Who knew a builder needs to be built ;D
I encountered CORS issues in my application. I felt that I properly implemented the logic but was still getting presented with Access-Control-Allow-Origin 403 Error. I tried every setting mentioned above but nothing worked.
I later discovered that my issue wasn't CORS related. I implemented a custom attribute
[Route("v1/[Controller]")]
[ServiceFilter(typeof(MyCustomFilterAttribute))]
public class MySpecialListsController
Calls made to the controller were properly making it to the method OnActionExecuting
public override void OnActionExecuting(ActionExecutingContext context)
The logic within the filter was throwing an exception and was presented as a CORS 403 error.
The answer of #HockeyJ is right, but you can do something more concise if wanted.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
//Or if you want to chose what to include
services.AddMvcCore()
.AddCors()
(...)
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//Cors
app.UseCors(builder =>
{
builder.AllowAnyHeader();
builder.AllowAnyMethod();
builder.AllowCredentials();
builder.AllowAnyOrigin(); // For anyone access.
//corsBuilder.WithOrigins("http://localhost:56573"); // for a specific url.
});
}
this is actually is a bug in dotnet core.
try to add cors policy right in the "Configure" method.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseCors(option =>
option.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
);
}

How do you enable cross-origin requests (CORS) in ASP.NET Core MVC

I'd like to enable CORS on an API built with ASP.NET Core MVC, but all the current documents refer to earlier versions of that framework.
The notes on the new Cors features are very light, but I was able to get it working in my solution by looking at the new classes and methods. My Web API startup.cs looks like this. You can see how you can construct your origins and policies her by using the new CorsPolicy class. And enabling CORS with the AddCors and UseCors methods.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
//Add Cors support to the service
services.AddCors();
var policy = new Microsoft.AspNet.Cors.Core.CorsPolicy();
policy.Headers.Add("*");
policy.Methods.Add("*");
policy.Origins.Add("*");
policy.SupportsCredentials = true;
services.ConfigureCors(x=>x.AddPolicy("mypolicy", policy));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Configure the HTTP request pipeline.
app.UseStaticFiles();
//Use the new policy globally
app.UseCors("mypolicy");
// Add MVC to the request pipeline.
app.UseMvc();
}
You can also reference the policy in the controllers with the new attributes like so
[EnableCors("mypolicy")]
[Route("api/[controller]")]
I got it working using the following code:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyOrigin()));
}
You can chain AllowAnyHeader() and/or AllowAnyMethod() to the configure action if needed.
To configure it for the complete app:
public void Configure(IApplicationBuilder app)
{
app.UseCors("AllowAll");
}
Or just for a controller:
[EnableCors("AllowAll")]
public class HomeController : Controller
{
// ...
}
--
Update: configuring CORS for all requests can be done a bit easier:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddCors();
}
public void Configure(IApplicationBuilder app)
{
app.UseCors(builder =>
{
builder.WithOrigins("http://some.origin.com")
.WithMethods("GET", "POST")
.AllowAnyHeader();
});
}
For more information, refer to the docs.
In the most recent RC2 of ASP.NET Core.
The NuGet packages are
"Microsoft.AspNetCore.Owin": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Cors": "1.0.0-rc2-final",
In Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddCors();
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseCors(builder => builder
.AllowAnyOrigin());
app.UseMvc();
}
Support for CORS is currently in development. Following issue is tracking that:
https://github.com/aspnet/Mvc/issues/498
Update (3/28/2015):
This feature has been checked in and should be available in the next release.
cs1929 the method services.ConfigureCors(...) does no more exist. It is combined to AddCors:
services.AddCors(options =>
options.AddPolicy("AllowAllOrigins", builder => builder.AllowAnyOrigin()));
Install : Microsoft.AspNetCore.Cors
In Configure method:
app.UseCors(builder =>
builder.WithOrigins("http://some.origin.com"));

Categories