Access-Control-Allow-Origin: * allows any website to access your resources. Always specify exact origins in production.
ASP.NET Core has first-class CORS support built-in. This is the recommended approach for all new .NET applications.
// Program.cs (ASP.NET Core 6+)
var builder = WebApplication.CreateBuilder(args);
// Add CORS policy
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.WithOrigins("https://example.com")
.AllowAnyMethod()
.AllowAnyHeader();
});
});
builder.Services.AddControllers();
var app = builder.Build();
// Enable CORS middleware
app.UseCors();
app.MapControllers();
app.Run();
Allow multiple specific origins (issue #146):
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.WithOrigins(
"https://example.com",
"https://app.example.com",
"https://admin.example.com"
)
.AllowAnyMethod()
.AllowAnyHeader();
});
});
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.WithOrigins("https://example.com")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials(); // Enable credentials
});
});
Define different policies for different endpoints:
builder.Services.AddCors(options =>
{
// Restricted policy for APIs
options.AddPolicy("ApiPolicy", policy =>
{
policy.WithOrigins("https://example.com")
.WithMethods("GET", "POST")
.WithHeaders("Content-Type", "Authorization")
.AllowCredentials();
});
// Open policy for public endpoints
options.AddPolicy("PublicPolicy", policy =>
{
policy.AllowAnyOrigin()
.WithMethods("GET")
.AllowAnyHeader();
});
});
// Apply to specific endpoints
app.MapControllers().RequireCors("ApiPolicy");
using Microsoft.AspNetCore.Cors;
[ApiController]
[Route("api/[controller]")]
[EnableCors("ApiPolicy")] // Apply to controller
public class DataController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return Ok(new { message = "CORS enabled" });
}
[HttpPost]
[EnableCors("PublicPolicy")] // Override for specific action
public IActionResult Post([FromBody] Data data)
{
return Ok(data);
}
}
For applications still using ASP.NET Framework (not Core):
Install the NuGet package:
Install-Package Microsoft.AspNet.WebApi.Cors
Enable in WebApiConfig.cs:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Enable CORS
var corsAttr = new EnableCorsAttribute(
origins: "https://example.com",
headers: "*",
methods: "*"
);
config.EnableCors(corsAttr);
// Other Web API configuration...
config.MapHttpAttributeRoutes();
}
}
Or use the attribute on controllers:
[EnableCors(origins: "https://example.com", headers: "*", methods: "*")]
public class TestController : ApiController
{
public IHttpActionResult Get()
{
return Ok(new { message = "CORS enabled" });
}
}
If you don't have access to configure IIS, add headers in Global.asax or page code:
// Global.asax.cs
protected void Application_BeginRequest(object sender, EventArgs e)
{
string origin = Request.Headers["Origin"];
string[] allowedOrigins = {
"https://example.com",
"https://app.example.com"
};
if (allowedOrigins.Contains(origin))
{
Response.AppendHeader("Access-Control-Allow-Origin", origin);
Response.AppendHeader("Vary", "Origin");
Response.AppendHeader("Access-Control-Allow-Credentials", "true");
}
Response.AppendHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
Response.AppendHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
// Handle preflight
if (Request.HttpMethod == "OPTIONS")
{
Response.AppendHeader("Access-Control-Max-Age", "86400");
Response.StatusCode = 204;
Response.End();
}
}
Or in individual pages:
// In Page_Load or button click handler
Response.AppendHeader("Access-Control-Allow-Origin", "https://example.com");
Note: This approach is compatible with IIS6, IIS7 Classic Mode, and IIS7 Integrated Mode.
For comprehensive testing instructions including curl commands, browser DevTools usage, and troubleshooting common CORS errors, see the CORS Testing Guide.
The content on this site stays fresh thanks to help from users like you! If you have suggestions or would like to contribute, fork us on GitHub.
Save 39% on CORS in Action with promotional code hossainco at manning.com/hossain