.NET Core / Web API71 min total · 19 parts
Building REST APIs with ASP.NET Core: Routing, Middleware, and Dependency Injection
Part 13 of 19 · ~1 min
CORS
Ridgeline's members hit Bench from a browser SPA at bench.ridgeline.edu, talking to the API at api.bench.ridgeline.edu — a different origin, by the browser's definition, even though both are Ridgeline's own domains. CORS is what decides whether the browser lets that cross-origin JavaScript call through at all; it's a rule the browser enforces on scripts it's running, not a gate on Bench's own server — a kiosk hitting the API directly, or curl, isn't touched by it.
builder.Services.AddCors(options =>
{
options.AddPolicy("BenchWeb", policy =>
policy.WithOrigins("https://bench.ridgeline.edu", "https://kiosk.ridgeline.edu")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
app.UseCors("BenchWeb"); // must run before UseAuthorization, and before MapControllers
Early on, chasing down a CORS error in the browser console at 11 PM, Theo reached for the fastest-looking fix:
policy.AllowAnyOrigin().AllowCredentials(); // looked like it would just make the error go away
It didn't quietly work — it refused to start at all. This combination isn't just something the CORS spec frowns on; ASP.NET Core's own CORS middleware throws an explicit InvalidOperationException the moment that policy is built: "The CORS protocol does not allow specifying a wildcard (any) origin and credentials at the same time." Confirmed directly — Bench's own app crashed on the next request that touched the CORS policy, not just a hypothetical browser somewhere rejecting it later. That's arguably the better outcome: it's a hard, immediate failure instead of a policy that quietly does nothing useful, or worse, that a browser silently accepts under some configurations and not others. The actual fix was what it should have been from the start — list bench.ridgeline.edu and kiosk.ridgeline.edu explicitly, which is exactly what the policy above does.