Chapter 04

Request Pipeline

Trực quan hóa hành trình của một HTTP request qua các middleware

Interactive Pipeline Visualizer

Chọn một kịch bản và nhấn "GỬI REQUEST" để xem request di chuyển qua từng middleware trong ASP.NET Core pipeline.

📨 Request HTTP In
🔀 Routing UseRouting()
🔎 Authentication UseAuthentication()
❌ 401
Unauthorized
🔒 Authorization UseAuthorization()
⛔ 403
Forbidden
🎯 Endpoint Controller / API
[--:--] Sẵn sàng. Chọn kịch bản và nhấn "GỬI REQUEST".

Middleware Pipeline Chi Tiết

Mỗi middleware trong pipeline có một nhiệm vụ cụ thể. Request đi qua từng middleware theo thứ tự, và bất kỳ middleware nào cũng có thể short-circuit (dừng pipeline sớm) nếu cần.

🔀
Step 1
UseRouting()
Xác định endpoint nào sẽ xử lý request dựa trên URL pattern và HTTP method. Không thực thi endpoint, chỉ "chọn" nó và gán vào HttpContext.
Nếu lỗi Không tìm thấy endpoint phù hợp → trả về 404 Not Found (xử lý ở cuối pipeline).
🔎
Step 2
UseAuthentication()
Đọc credentials từ request (cookie, JWT trong Authorization header), validate chúng, tạo ClaimsPrincipal, và gán vào HttpContext.User.
Nếu lỗi Token không hợp lệ hoặc hết hạn → HttpContext.User sẽ là anonymous. Nếu endpoint yêu cầu authentication, Authorization middleware sẽ trả 401 Unauthorized.
🔒
Step 3
UseAuthorization()
Kiểm tra endpoint có yêu cầu authorization không ([Authorize]), nếu có thì đánh giá policies, roles, và claims của user hiện tại.
Nếu lỗi User chưa authenticated → 401 Challenge. User đã authenticated nhưng không đủ quyền → 403 Forbid.
🎯
Step 4
Endpoint Execution
Chạy controller action hoặc minimal API handler. Đây là nơi business logic của bạn được thực thi — query database, xử lý dữ liệu, trả về response.
Nếu lỗi Exception trong action → 500 Internal Server Error (nếu không có exception middleware).

Challenge vs Forbid: 401 vs 403

Hai kết quả thất bại của authorization có ý nghĩa rất khác nhau. Hiểu đúng sự khác biệt giúp bạn debug và thiết kế security flow chính xác.

401
Unauthorized (Challenge)
"Bạn chưa xác thực danh tính"
Khi nào
User chưa đăng nhập hoặc token đã hết hạn / không hợp lệ.
Hành vi
Cookie scheme: redirect đến login page.
JWT / API: trả về 401 JSON response.
Code
return Challenge();
403
Forbidden (Forbid)
"Bạn đã xác thực nhưng không đủ quyền"
Khi nào
User đã đăng nhập nhưng không có role/permission cần thiết.
Hành vi
Cookie scheme: redirect đến Access Denied page.
JWT / API: trả về 403 JSON response.
Code
return Forbid();
Tên "401 Unauthorized" trong HTTP spec thực ra có nghĩa là "Unauthenticated" — đây là một đặt tên lịch sử gây nhầm lẫn. Nhớ: 401 = chưa đăng nhập, 403 = đã đăng nhập nhưng không đủ quyền.

Thêm Custom Middleware vào Pipeline

Bạn có thể chèn middleware tùy chỉnh vào bất kỳ vị trí nào trong pipeline. Vị trí đặt middleware quyết định nó có quyền truy cập thông tin gì.

C#
// Middleware log mọi request (đặt TRƯỚC auth)
app.Use(async (context, next) =>
{
    var start = DateTime.UtcNow;
    Console.WriteLine($"▶ {context.Request.Method} {context.Request.Path}");

    await next(); // Gọi middleware tiếp theo

    var elapsed = DateTime.UtcNow - start;
    Console.WriteLine($"◀ {context.Response.StatusCode} ({elapsed.TotalMilliseconds}ms)");
});

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

// Middleware kiểm tra thêm sau authorization (ví dụ: rate limiting)
app.Use(async (context, next) =>
{
    if (IsRateLimited(context))
    {
        context.Response.StatusCode = 429; // Too Many Requests
        return; // Short-circuit — không gọi next()
    }
    await next();
});

app.MapControllers();

Pipeline với Custom Middleware

Middleware tùy chỉnh (màu vàng) có thể được chèn vào trước hoặc sau các built-in middleware:

📜 Logging MW
🔀 UseRouting
🔎 UseAuthentication
🔒 UseAuthorization
⚡ Rate Limiter
🎯 Endpoint
Gọi await next() để chuyển request đến middleware tiếp theo. Nếu không gọi next(), pipeline sẽ bị short-circuit — các middleware phía sau sẽ không được thực thi. Đây là cách bạn trả về response sớm (ví dụ: 429, 401).

Tại sao thứ tự Middleware quan trọng?

Authorization middleware cần biết (1) endpoint nào đã được chọn (từ Routing) và (2) user là ai (từ Authentication). Nếu đặt sai thứ tự, Authorization sẽ luôn thấy user chưa authenticated và từ chối mọi request.

✅ ĐÚNG
1 UseRouting()
2 UseAuthentication()
3 UseAuthorization()
4 MapControllers()
❌ SAI
1 UseAuthorization() ⚠
2 UseAuthentication() ⚠
3 UseRouting()
4 MapControllers()
Với thứ tự sai, UseAuthorization() chạy trước UseAuthentication() nên HttpContext.User luôn là anonymous. Kết quả: mọi request đến endpoint có [Authorize] sẽ bị trả về 401, dù user có token hợp lệ.