TL;DR
- Middleware order in ASP.NET Core defines your app’s security, performance, and request handling correctness.
- Recommended order: exception handling → HSTS → HTTPS redirection → static files → routing → CORS → authentication → authorization → endpoint mapping.
- Incorrect order can break authentication, CORS, or routing, and expose your app to security issues.
- Follow the “onion model”: outer middleware runs first on requests, last on responses.
- Always test your middleware pipeline after changes to prevent subtle bugs and security risks.
Getting your middleware pipeline right in ASP.NET Core is crucial for security, performance, and correctness. The order in which you register middleware defines the order it executes on a request and the reverse order it executes on a response. A wrong sequence can cause anything from broken authentication to security vulnerabilities.
Let’s cut to the chase. Here is the recommended, battle-tested middleware order for most modern ASP.NET Core applications.
The Recommended Program.cs
Pipeline Order
Think of the request pipeline as a series of gates. A request must pass through each one in the correct sequence. Here’s a typical Program.cs
setup that demonstrates this flow:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// --- The Recommended Middleware Order ---
// 1. Exception Handling: Catches exceptions thrown in later middleware.
// Should be first so it can handle errors from everything that runs after it.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// 2. HSTS: Enforces HTTPS in production.
app.UseHsts();
}
// 3. HTTPS Redirection: Redirects HTTP requests to HTTPS.
app.UseHttpsRedirection();
// 4. Static Files: Serves static files (JS, CSS, images) and short-circuits.
// Placed early to avoid unnecessary processing for static content.
app.UseStaticFiles();
// 5. Routing: Determines which endpoint to execute.
app.UseRouting();
// 6. CORS: Must come after UseRouting and before UseAuthorization.
// This allows policy evaluation based on the selected endpoint's metadata.
app.UseCors();
// 7. Authentication: Identifies the user. Who are you?
app.UseAuthentication();
// 8. Authorization: Checks if the user has permission. Are you allowed?
app.UseAuthorization();
// 9. Endpoint Mapping: Executes the endpoint selected by routing.
// This is where your app.MapGet(), app.MapPost(), etc., are executed.
app.MapControllers(); // Or app.MapRazorPages(), app.MapGet(...), etc.
app.Run();
Why This Order Matters
This sequence isn’t arbitrary. It’s designed for efficiency and correctness:
- Diagnostics First: Exception handlers are at the top to catch anything that goes wrong down the line.
- Short-Circuiting Early:
UseStaticFiles
andUseHttpsRedirection
can handle requests and stop the pipeline immediately, saving resources. - Auth After Routing: A common pitfall is placing
UseAuthentication
orUseAuthorization
beforeUseRouting
. This is inefficient because you don’t even know which endpoint the user is trying to access yet. Routing needs to happen first so the system can identify the endpoint and any associated authorization policies.
A Quick Mental Model
Think of middleware as wrapping layers, like an onion. The first middleware added is the outermost layer, it sees the request first and the response last. The last middleware is the innermost layer. This “first in, last out” model helps ensure that concerns like security and error handling wrap the core application logic correctly.
FAQ
Why does middleware order matter in ASP.NET Core?
What is the recommended order for middleware in ASP.NET Core?
Why should exception handling middleware come first?
Where should CORS middleware be placed?
What happens if authentication or authorization is registered before routing?
Can static files middleware be placed anywhere in the pipeline?
How does middleware order affect security?
What is the “onion model” of middleware?
How can you debug middleware order issues?
Is the recommended order always required?
See other aspnet-core posts
- How to Prevent Common Web Attacks in ASP.NET Core: Security Best Practices and Example
- Stop Repeating Yourself: Cleaner API Responses in ASP.NET Core
- Custom routing constraint in AspNet core
- Understanding dotnet dev-certs https: Local HTTPS for .NET Development
- ASP.NET Core HTTP Logging Middleware: 10 Practical Micro Tips
- Mastering Request and Response Body Logging in ASP.NET Core Middleware
- ASP.NET Core Middleware: Difference Between Use, Run, and Map Explained
- Implementing Request Throttling Middleware in ASP.NET Core Using MemoryCache and Per-IP Limits