I am trying to setup 2 CORS policies. One as an api default and the other to use on Controllers
as I need them. The reason I want to do this is because I have an endpoint that takes in an object with email info and sends an email (to use with the contact me box on my webpage) and have it only accept requests from my domain.
My startup.cs
file snippet:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("Example",
builder => builder.WithOrigins("http://www.example.com"));
options.AddPolicy("AllowAll",
builder => builder.AllowAnyOrigin());
});
services.AddMvc();
//other configure stuff
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseCors(builder =>
{
builder.AllowAnyHeader();
builder.AllowAnyMethod();
builder.WithOrigins("AllowAll");
});
app.UseMvcWithDefaultRoute();
}
My emailcontroller.cs
file:
using System.Threading.Tasks;
using MyAPI.Models;
using MyAPI.Services;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
namespace MyAPI.Controllers
{
[Produces("application/json")]
[Route("api/Email")]
[EnableCors("Example")]
public class EmailController : Controller
{
private readonly IEmailSender _emailSender;
public EmailController(IEmailSender emailSender)
{
_emailSender = emailSender;
}
[HttpPost]
public async Task Post([FromBody] Email email)
{
await _emailSender.SendEmailAsync(email);
}
}
}
Javascript used to send email:
function sendEmail(email)
{
var urlToApi = "http://<ipToApi>:5000/api";
$.ajax({
method: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(email),
url: urlToApi + "/email/",
success: function(data) {
console.log(data);
console.log('probably sent');
},
error: function(jqXHR, textStatus, errorThrown){
console.log(textStatus);
alert("There was like, an error doing that");
}
});
}
This is what I get trying to send from http://www.example.com
XMLHttpRequest cannot load http://<ipToApi>:5000/api/email/.
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://www.example.com' is therefore not allowed access.
EDIT
This works:
services.AddCors(options =>
{
options.AddPolicy("Example",
builder => builder.WithOrigins("http://www.example.com")
.AllowAnyHeader()
.AllowAnyMethod());
options.AddPolicy("AllowAll",
builder => builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
});
There are three ways to enable CORS: In middleware using a named policy or default policy. Using endpoint routing. With the [EnableCors] attribute.
CORS means cross-origin resource sharing. You'll see more in just a minute, but in a nutshell, CORS is a mechanism—an HTTP protocol, to be exact—that allows web applications to access resources hosted on different domains (or origins.)
Configure Method
app.UseRouting();
app.UseCors("CorsApi");
app.UseAuthentication();
ConfigureServices method
services.AddCors(options =>
{
options.AddPolicy("CorsApi",
builder => builder.WithOrigins("http://localhost:4200", "http://mywebsite.com")
.AllowAnyHeader()
.AllowAnyMethod());
});
To set a default CORS policy use app.UseCors(string policyName)
overload.
Your CORS requests will be failing because you are rejecting all headers and methods. From what I read, the CORS specification states that you shouldn't set any headers at all if any of the checks fail. See implementation here, this is most likely why your client will be receiving the standard No 'Access-Control-Allow-Origin' header is present
error, as no headers are added at all, even though the Origin
check passes.
The following should work as expected, and your [EnableCors(...)]
decorator should override the default!
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("Example",
builder => builder.WithOrigins("http://www.example.com")
.AllowAnyHeader()
.AllowAnyMethod());
options.AddPolicy("AllowAll",
builder => builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
});
services.AddMvc();
//other configure stuff
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseCors("AllowAll"); //Default
app.UseMvcWithDefaultRoute();
}
You may need to add .AllowCredentials()
to your policies, but I am not sure. Read here perhaps?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With