Skip to content
Shiny.Net.HttpServer v1 - A lightweight feature rich HTTP Server - Tunnels, Websockets, AOT, ASPNET Featureset, & Works EVERYWHERE!Let me see!

CORS

app.UseCors(p => p.WithOrigins("https://app.example.com").AllowAnyHeader().AllowAnyMethod());

No container needed. For named policies, register them and apply per endpoint:

builder.Services.AddCors(o =>
{
o.AddDefaultPolicy(p => p.WithOrigins("https://app.example.com").AllowAnyHeader().AllowAnyMethod());
o.AddPolicy("public", p => p.AllowAnyOrigin().WithMethods("GET"));
});
var app = builder.Build();
app.UseCors();
app.OnGet("/status", ctx => …).RequireCors("public");
app.OnGet("/internal", ctx => …).DisableCors();

On generated endpoints the same thing is an attribute, emitted as metadata at compile time:

[Route("/api")]
[EnableCors("public")]
public class PublicEndpoints
{
[Get("/status")] public string Status() => "ok";
[Get("/internal")] [DisableCors] public string Internal() => …;
}

A method’s attribute replaces the class’s, because a route has exactly one CORS policy — and Disable anywhere wins over Enable.

Method Effect
WithOrigins(…) Named origins. The actual origin is echoed back
AllowAnyOrigin() *
SetIsOriginAllowed(predicate) Decide per request
WithMethods(…) / AllowAnyMethod()
WithHeaders(…) / AllowAnyHeader() Request headers the browser may send
WithExposedHeaders(…) Response headers script may read beyond the safelisted ones
AllowCredentials() / DisallowCredentials() Cookies and Authorization
SetPreflightMaxAge(TimeSpan) How long a browser may cache the preflight answer

The wildcard is only emitted when the policy really does not care who is asking. With credentials, or with named origins, the actual origin is echoed and Vary: Origin is appended — appended, not set, because a handler’s own Vary is not something to trample. Response headers go on from an OnStarting callback for the same reason.

Preflights are answered by the middleware and never forwarded to a handler.

UseCors() is ordinary middleware and belongs early — before authentication and before routing.

A CORS preflight is an OPTIONS to a path that only answers GET, so the router would 405 it and the real request would never be sent. And a browser sends a preflight without credentials, so an authentication middleware ahead of CORS would see an anonymous request and 401 the browser’s question.

Per-endpoint policies still work, because the middleware asks the router which endpoint the request would reach — for a preflight, the one its Access-Control-Request-Method names.