I'm using Visual Studio to publish an ASP.NET Core 2.1 app to AWS Lambda (serverless). No matter what I've tried I cannot get CORS to work.
All I really want to do is add the header access-control-allow-origin globally to my web app.
Has anyone ever successfully added headers to an ASP.NET Core 2.1 Serverless app?
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// AddCors must be before AddMvc
services.AddCors();
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// UseCors must be before UseMvc
app.UseCors(builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
// Also tried this
// app.UseCors(
// o => o.WithOrigins("http://example.com").AllowAnyMethod()
//);
app.UseMvc();
}
No CORS headers are added to my pages. I'm using Chrome dev tools to inspect my headers. I should see them on the homepage (for example) correct?
Any ideas? I'm dyin over here. Thanks!
EDIT
This application only uses API Gateway, Lambda and a few other services. It's great because I'm only charged when someone hits my app. There are no hourly charges. No EC2 or ELB which is amazing.
Also, I almost added this to my original post. The article #sturcotte06 references has a gotcha.
The API Gateway (automatically generated) uses the ANY method in a proxy integration. The above article says this...
Important
When applying the above instructions to the ANY method in a proxy integration, any applicable CORS headers will not be set. Instead, your backend must return the applicable CORS headers, such as Access-Control-Allow-Origin.
Ugh! So it's saying I must do this on the backend (Startup.cs right?) which is exactly what seems to get ignored when published.
For whatever reason app.UseCors does not work in my scenario. However, app.Use does...
app.Use((context, next) =>
{
context.Response.Headers["Access-Control-Allow-Origin"] = "https://example.com";
return next.Invoke();
});
app.UseMvc();
Related
I developed an API to give public access to some company data, which is of no value to hackers. It's public data that can be sourced from other websites.
I developed the project using default Visual Studio ASP.Net Core API templates. One thing I noticed it's using CORS and I don't know how it got in here to be honest.
However, the default Policy is set as any domain, any method and any header:
builder.Services.AddCors(p =>
p.AddPolicy("corsapp", builder =>
{
builder.WithOrigins("*").AllowAnyMethod().AllowAnyHeader();
}));
Do I even need CORS, if I am only allowing the API to run from a single origin, which already has HTTPS?
What benefit, when the API works as is?
Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
//do I really need this!?!
builder.Services.AddCors(p => p.AddPolicy("corsapp", builder =>
{
builder.WithOrigins("*").AllowAnyMethod().AllowAnyHeader();
}));
var startup = new Startup(builder.Configuration);
startup.ConfigureServices(builder.Services);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
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();
}
startup.Configure(app);
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
//why!?!
app.UseCors("corsapp");
app.UseAuthorization();
app.MapControllers();
app.Run();
UPDATE
I've re-worded my OP based on Rahul's excellent video about CORS from Chen's answer below. However, I am still confused if I should configure CORS here to give a specific single origin as I am more worried someone after me may not configure this Policy correctly if the API is required in more than two places.
Thanks
You would need to know if your program provides API responses to client applications loaded from other domains to determine if you need to enable CORS.
For example, there are two cases where no action is needed for CORS support:
Swagger UI is hosted on the same server as the application itself (same host and port).
The application is located behind a proxy that enables the required CORS headers. This may already be covered within your organization.
You can get a better understanding and use of CORS through this link and this official documentation.
In my project, the negotiate, connect and start API calls all contain the required access-control-allow-origin header. However, as soon as SignalR calls the ping method, it throws the following error:
Access to XMLHttpRequest at 'https://backend.url/signalr/signalr/ping&_=1643292246714'
from origin 'https://frontend.url' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
I already modified my Startup.cs file according to Microsoft's documentation. I the old version, I was using the MapSignalR method instead.
public class Startup {
public void Configuration(IAppBuilder app) {
// Branch the pipeline here for requests that start with "/signalr"
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR. By default this will allow all origins.
map.UseCors(CorsOptions.AllowAll);
map.RunSignalR();
});
app.UseCors(CorsOptions.AllowAll);
}
}
However, this change didn't have any effect. The CORS error still persists. Any idea what's wrong here?
I'm using Microsoft.AspNet.SignalR 2.4.2 and Microsoft.Owin.Cors 4.2.0 with .NET Framework 4.8.
I also don't understand, why it's calling /signalr/signalr in the URL.
You should configure your CORS like (the order is important):
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder => builder.WithOrigins(YourOriginsHere)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
.SetIsOriginAllowed((host) => true));
});
Note: Avoid putting * in the origins, it is better to create an array of strings with the possible origins, ideally reading it from configuration.
Update: For .NET Framework see how to enable CORS from this Microsoft documentation.
The actual problem was a bug in the client library I use. The solution was to update my client-side npm package signalr-asp-net. I still had version 1.0.0 and updated to 1.0.3. The problem is gone now.
I have an SPA with React Typescript and .Net core 2.1.
The application has been deployed to an webapp in Azure.
The problem occurs after I have done a refresh on the web application, but not on the first login.
All my request goes through as well.
I have enabled Cors on the server side and also implemented cors in the backend.
I think the issue occurs inside registerServiceWorker.ts but not sure how to fix it.
I have not done any configurations in this file so it's only the default values.
Hope someone can point me in the right directions.
Backend .net core:
public void ConfigureServices(IServiceCollection services)
{
// cors
services.AddCors(options =>
{
options.AddPolicy("AllowAll",
builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// global policy
app.UseCors("AllowAll");
}
[Route("api/[controller]")]
[EnableCors("AllowAll")]
[Authorize]
[ApiController]
public class AuthController : ControllerBase
Found out why it was redirecting.
Had some issues with refreshing the token from server that did not work correctly.
I am trying to enable CORS within my ASP.NET Core API and allow passing cookies from my client application (Angular 6). However, whenever I attempt to hit an endpoint through my Angular application, I am receiving the following error:
Response to preflight request doesn't pass access control check: The
value of the 'Access-Control-Allow-Origin' header in the response must
not be the wildcard '*' when the request's credentials mode is
'include'
Within my Startup.cs file, I have CORS enabled under ConfigureServices like:
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithOrigins("http://localhost:4200"));
});
and under Configure:
app.UseCors("CorsPolicy");
In my Angular 6 application, I am calling the endpoint with a token like this:
this.http.get<T>(url, { headers: new HttpHeaders({ 'X-XSRF-TOKEN': token}), withCredentials: true });
The error is confusing because I am explicitly setting the allowed origins in .WithOrigins() within my .AddCors function, yet it's still saying there is only a wild card.
If this is hosted on Azure. Check the CORS settings in Azure AppService. The configurations there will override any other Cors configuration even in the .net core middleware.
within
public void ConfigureServices(IServiceCollection services)
after
services.AddMvc()
try
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
then within
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
try
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors("CorsPolicy");
Once you do the above to your asp.net core api, you can test as shown below
if you can get the options request to the api to respond with the above headers, you have resolved the api CORS issue, then its time to move onto the angular 6 code.
I have a very peculiar problem.
I am developing a serverless AWS Lambda based WebAPI (.NET core 2.0).
I added a controller and all the required CORS settings in the Setup.cs.
I was successfully able to use the API after all the above steps.
I went ahead and added a second controller and the CORS settings had no effect!
I tried multiple methods such as adding the EnableCors to the controllers explicitly and adding an interceptor for the OPTIONS but again no effect.
I removed the additional controller and everything is back to normal (CORS has an effect).
Is there a restriction on CORS and the number of controllers in a single Lambda function for the .NET core?
Edit 1 : Adding code segments for better illustration
In ConfigureServices
var origins = Configuration.GetSection("AllowedCORS").AsEnumerable().Select(x => x.Value);
services.AddCors(o => o.AddPolicy("AllOrigins", builder =>
{
builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
}));
Then in Configure
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors("AllOrigins");
app.UseAuthentication();
app.UseMvc();
}
I managed to resolve the issue by manually adding an Options handler in the controller and returning 200 OK.
Lambda does allow users to enable CORS but for some reason that method did not work for me (too many errors during setup)
At present i am restricting one Lambda function to one controller thereby giving me the freedom to modify only a certain set of the APIs.