Section 2 of 5

Built-in Middleware

🎯 What You'll Learn

  • Common built-in middleware components
  • Static Files middleware
  • Routing middleware
  • Authentication and Authorization
  • CORS middleware
  • Response Compression
  • HTTPS Redirection
  • Session middleware
  • Configuring each middleware

Overview of Built-in Middleware

ASP.NET Core provides many middleware components out of the box for common tasks:

Middleware Purpose Method
Exception Handler Catch and handle exceptions UseExceptionHandler()
HTTPS Redirection Redirect HTTP to HTTPS UseHttpsRedirection()
Static Files Serve static files (CSS, JS, images) UseStaticFiles()
Routing Match requests to endpoints UseRouting()
CORS Enable cross-origin requests UseCors()
Authentication Identify users UseAuthentication()
Authorization Check user permissions UseAuthorization()
Session Manage user sessions UseSession()
Response Compression Compress responses UseResponseCompression()
Response Caching Cache responses UseResponseCaching()

1. Static Files Middleware

Serves static files (HTML, CSS, JavaScript, images) from the wwwroot folder.

Basic Usage C#
app.UseStaticFiles();

// Now files in wwwroot are accessible:
// wwwroot/css/style.css → http://localhost:5000/css/style.css
// wwwroot/images/logo.png → http://localhost:5000/images/logo.png

Custom Configuration

Serve from Different Folder C#
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
    RequestPath = "/files"
});

// MyStaticFiles/document.pdf → http://localhost:5000/files/document.pdf

Enable Directory Browsing

Directory Browsing C#
builder.Services.AddDirectoryBrowser();

app.UseStaticFiles();
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "wwwroot")),
    RequestPath = "/browse"
});
⚠️ Security Warning

Never enable directory browsing in production! It exposes your file structure.

2. Routing Middleware

Matches incoming requests to endpoints (controllers, Razor Pages, minimal APIs).

Routing Setup C#
app.UseRouting();

// Define endpoints
app.MapControllers();
app.MapGet("/hello", () => "Hello World!");
ℹ️ Routing in ASP.NET Core 6+

In ASP.NET Core 6+, UseRouting() is often implicit. You can call MapControllers() directly without explicitly calling UseRouting().

3. CORS Middleware

CORS (Cross-Origin Resource Sharing) allows requests from different domains.

CORS Configuration C#
// 1. Configure CORS policy
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowInvenTrackFrontend", policy =>
    {
        policy.WithOrigins("https://inventrackapp.com")
              .AllowAnyMethod()
              .AllowAnyHeader();
    });
});

// 2. Use CORS middleware
app.UseCors("AllowInvenTrackFrontend");

Common CORS Policies

Allow All (Development Only!) C#
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAll", policy =>
    {
        policy.AllowAnyOrigin()
              .AllowAnyMethod()
              .AllowAnyHeader();
    });
});
Allow Specific Origins C#
builder.Services.AddCors(options =>
{
    options.AddPolicy("Production", policy =>
    {
        policy.WithOrigins(
                  "https://inventrackapp.com",
                  "https://admin.inventrackapp.com")
              .AllowAnyMethod()
              .AllowAnyHeader()
              .AllowCredentials(); // Allow cookies
    });
});

4. Authentication & Authorization

Authentication Middleware

Identifies who the user is based on credentials (JWT, cookies, etc.).

JWT Authentication C#
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidIssuer = builder.Configuration["Jwt:Issuer"],
            ValidAudience = builder.Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
        };
    });

app.UseAuthentication();

Authorization Middleware

Checks if the authenticated user has permission to access a resource.

Authorization C#
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("AdminOnly", policy =>
        policy.RequireRole("Admin"));
    
    options.AddPolicy("InventoryManager", policy =>
        policy.RequireClaim("Permission", "ManageInventory"));
});

app.UseAuthorization();
⚠️ Order Matters!

UseAuthentication() must come before UseAuthorization(). You can't check permissions before identifying the user!

5. HTTPS Redirection

Automatically redirects HTTP requests to HTTPS.

HTTPS Redirection C#
app.UseHttpsRedirection();

// http://localhost:5000 → https://localhost:5001

Custom Configuration

Custom HTTPS Port C#
builder.Services.AddHttpsRedirection(options =>
{
    options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
    options.HttpsPort = 443;
});

6. Response Compression

Compresses responses to reduce bandwidth usage.

Response Compression C#
builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<GzipCompressionProvider>();
    options.Providers.Add<BrotliCompressionProvider>();
});

app.UseResponseCompression();

7. Session Middleware

Manages user session data across requests.

Session Configuration C#
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromMinutes(30);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});

app.UseSession();

Using Session

Session Usage C#
app.MapGet("/set-session", (HttpContext context) =>
{
    context.Session.SetString("Username", "John");
    return "Session set!";
});

app.MapGet("/get-session", (HttpContext context) =>
{
    var username = context.Session.GetString("Username");
    return $"Username: {username}";
});

8. Response Caching

Response Caching C#
builder.Services.AddResponseCaching();

app.UseResponseCaching();

// Use with [ResponseCache] attribute on controllers
[ResponseCache(Duration = 60)]
public IActionResult GetProducts()
{
    return Ok(_products);
}

Complete InvenTrack Example

Program.cs (Full Pipeline) C#
var builder = WebApplication.CreateBuilder(args);

// Services
builder.Services.AddControllers();
builder.Services.AddResponseCompression();
builder.Services.AddResponseCaching();

// CORS
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowFrontend", policy =>
        policy.WithOrigins("https://inventrackapp.com")
              .AllowAnyMethod()
              .AllowAnyHeader());
});

// Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer();

builder.Services.AddAuthorization();

var app = builder.Build();

// Middleware Pipeline
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseResponseCompression();
app.UseResponseCaching();

app.UseRouting();

app.UseCors("AllowFrontend");

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

Key Takeaways

  • Static Files: Serve files from wwwroot
  • Routing: Match requests to endpoints
  • CORS: Enable cross-origin requests with policies
  • Authentication: Identify users (JWT, cookies, etc.)
  • Authorization: Check permissions (must come after authentication)
  • HTTPS Redirection: Force HTTPS in production
  • Response Compression: Reduce bandwidth with Gzip/Brotli
  • Session: Store per-user data across requests
  • Response Caching: Cache responses for performance
  • Middleware order is critical (covered in Section 4)
🎯 Next Steps

You now know the most common built-in middleware! In the next section, we'll learn how to Create Custom Middleware—building your own middleware components for logging, request timing, API key validation, and more.