I am working on a simple booking platform and need to send CORS(Cross origin Requests) from jQuery to a web API running on .NET Core MVC.
AJAX calls
I am sending two ajax requests frequently, one to delete and one to add to a database which is using Entity Framework:
var deleteReservation = function (reservationID) {
var u = $.ajax({
url: url+"/api/booking/del",
method: "POST",
async: true,
xhrFields: {
withCredentials: true
},
data: { "id": reservationID }
}).done(function (data) {
refresh();
});
};
var book = function (reservation) {
var u = $.ajax({
url: url + "/api/booking/new",
method: "POST",
async: true,
xhrFields: {
withcredentials: true
},
data: { "reservation": JSON.stringify(reservation) }
}).done(function (data) {
console.log(data);
refresh();
});
};
Implementing Windows Authentification
I need these requests to be authorized via Windows Authentification. I have set up CORS on the API to allow it from the address specified in my appsettings.json under the "CORSOrigin"
key:
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddCors();
services.AddRouting();
services.AddEntityFrameworkSqlServer();
services.AddDbContext<BookingContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, BookingContext context)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseCors(builder =>
builder.WithOrigins($"{Configuration["CORSOrigin"]}").AllowAnyHeader().AllowCredentials());
app.UseMvc();
DbInitializer.Initialize(context);
}
API controller
And finally, here are my two methods in my BookingController.cs
that are called on reguest:
[Route("api/[controller]")]
[Authorize]
public class BookingController : Controller
{
private readonly BookingContext context;
public BookingController(BookingContext context)
{
this.context = context;
}
[HttpPost("new")]
public IActionResult book(String reservation) {
var r = JsonConvert.DeserializeObject<Reservation>(reservation);
context.Reservations.Add(new Reservation(r.SeatID, r.User, r.Date));
context.SaveChanges();
return Ok();
}
[HttpPost("del")]
public IActionResult deleteReservation(int id) {
var r = context.Reservations.SingleOrDefault(x => x.ID == id);
if (r == null) return NotFound("Can't found requested reservation.");
context.Reservations.Remove(r);
context.SaveChanges();
return Ok();
}
}
Problem: Working with IE, not in Chrome
Now the problem is that the requests all are working perfectly in Internet Explorer and I am able to utilize Windows Authentication, however, when I run these in Chrome or Opera, the deleteReservation(reservationID)
ajax gets authorized, but for the book(reservation)
I keep getting 401(Unauthorized).
Research
I played around with this problem for a few hours and arrived at a thought that it may be caused by incorrect preflight requests. I tried to implement a lot of solutions from these posts:
- POST AJAX request denied - CORS?
- WebAPI CORS with Windows Authentication - allow Anonymous OPTIONS request
- Web API 2.1 Windows Authentication CORS Firefox
- AJAX Post JQuery does not working CORS
Somu users, on the other hand, reported that it works in Chrome:
Conclusion
The specialty about my issue lies in the fact that it works in one controller method but not in the other. The difference in these two is only the way they work with the database (addition and deletion).
Please correct me if I were not accurate with some .NET terminology. I have only been working with it for a month. Thanks for anyone's time and helpfulness.