下图显示了 ASP.NET Core MVC 和 Razor Pages 应用的完整请求处理管道。 你可以在典型应用中了解现有中间件的顺序,以及在哪里添加自定义中间件。 你可以完全控制如何重新排列现有中间件,或根据场景需要注入新的自定义中间件。
上图中的“终结点”中间件为相应的应用类型(MVC 或 Razor Pages)执行筛选器管道。
向 Startup.Configure
方法添加中间件组件的顺序定义了针对请求调用这些组件的顺序,以及响应的相反顺序。 此顺序对于安全性、性能和功能至关重要。
下面的 Startup.Configure
方法按照建议的顺序增加与安全相关的中间件组件:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
// app.UseCookiePolicy();
app.UseRouting();
// app.UseRequestLocalization();
// app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
// app.UseSession();
// app.UseResponseCaching();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
在上述代码中:
UseCors
、UseAuthentication
和 UseAuthorization
必须按照上述顺序运行。UseCors
当前必须在 UseResponseCaching
之前运行。以下 Startup.Configure
方法将为常见应用方案添加中间件组件:
Strict-Transport-Security
标头。public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
在前面的示例代码中,每个中间件扩展方法都通过 Microsoft.AspNetCore.Builder 命名空间在 IApplicationBuilder 上公开。
UseExceptionHandler 是添加到管道的第一个中间件组件。 因此,异常处理程序中间件可捕获稍后调用中发生的任何异常。
尽早在管道中调用静态文件中间件,以便它可以处理请求并使其短路,而无需通过剩余组件。 静态文件中间件不提供授权检查。 可公开访问由静态文件中间件服务的任何文件,包括 wwwroot 下的文件。 若要了解如何保护静态文件,请参阅 ASP.NET Core 中的静态文件。
如果静态文件中间件未处理请求,则请求将被传递给执行身份验证的身份验证中间件 (UseAuthentication)。 身份验证不使未经身份验证的请求短路。 虽然身份验证中间件对请求进行身份验证,但仅在 MVC 选择特定 Razor Page 或 MVC 控制器和操作后,才发生授权(和拒绝)。
以下示例演示中间件排序,其中静态文件的请求在响应压缩中间件前由静态文件中间件进行处理。 使用此中间件顺序不压缩静态文件。 可以压缩 Razor Pages 响应。
public void Configure(IApplicationBuilder app)
{
// Static files aren't compressed by Static File Middleware.
app.UseStaticFiles();
app.UseResponseCompression();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
ASP.NET Core 附带以下中间件组件。 “顺序”列提供备注,以说明中间件在请求处理管道中的放置,以及中间件可能会终止请求处理的条件。 如果中间件让请求处理管道短路,并阻止下游中间件进一步处理请求,它被称为“终端中间件”。 若要详细了解短路,请参阅使用 IApplicationBuilder 创建中间件管道部分。
中间件 | 描述 | 顺序 |
---|---|---|
身份验证 | 提供身份验证支持。 | 在需要 HttpContext.User 之前。 OAuth 回叫的终端。 |
授权 | 提供身份验证支持。 | 紧接在身份验证中间件之后。 |
Cookie 策略 | 跟踪用户是否同意存储个人信息,并强制实施 cookie 字段(如 secure 和 SameSite )的最低标准。 |
在发出 cookie 的中间件之前。 示例:身份验证、会话、MVC (TempData)。 |
CORS | 配置跨域资源共享。 | 在使用 CORS 的组件之前。 由于此错误,UseCors 当前必须在 UseResponseCaching 之前运行。 |
诊断 | 提供新应用的开发人员异常页、异常处理、状态代码页和默认网页的几个单独的中间件。 | 在生成错误的组件之前。 异常终端或为新应用提供默认网页的终端。 |
转接头 | 将代理标头转发到当前请求。 | 在使用已更新字段的组件之前。 示例:方案、主机、客户端 IP、方法。 |
运行状况检查 | 检查 ASP.NET Core 应用及其依赖项的运行状况,如检查数据库可用性。 | 如果请求与运行状况检查终结点匹配,则为终端。 |
标头传播 | 将 HTTP 标头从传入的请求传播到传出的 HTTP 客户端请求中。 | |
HTTP 方法重写 | 允许传入 POST 请求重写方法。 | 在使用已更新方法的组件之前。 |
HTTPS 重定向 | 将所有 HTTP 请求重定向到 HTTPS。 | 在使用 URL 的组件之前。 |
HTTP 严格传输安全性 (HSTS) | 添加特殊响应标头的安全增强中间件。 | 在发送响应之前,修改请求的组件之后。 示例:转接头、URL 重写。 |
MVC | 用 MVC/Razor Pages 处理请求。 | 如果请求与路由匹配,则为终端。 |
OWIN | 与基于 OWIN 的应用、服务器和中间件进行互操作。 | 如果 OWIN 中间件处理完请求,则为终端。 |
响应缓存 | 提供对缓存响应的支持。 | 在需要缓存的组件之前。 UseCORS 必须在 UseResponseCaching 之前。 |
响应压缩 | 提供对压缩响应的支持。 | 在需要压缩的组件之前。 |
请求本地化 | 提供本地化支持。 | 在对本地化敏感的组件之前。 |
终结点路由 | 定义和约束请求路由。 | 用于匹配路由的终端。 |
SPA | 通过返回单页应用程序 (SPA) 的默认页面,在中间件链中处理来自这个点的所有请求 | 在链中处于靠后位置,因此其他服务于静态文件、MVC 操作等内容的中间件占据优先位置。 |
会话 | 提供对管理用户会话的支持。 | 在需要会话的组件之前。 |
静态文件 | 为提供静态文件和目录浏览提供支持。 | 如果请求与文件匹配,则为终端。 |
URL 重写 | 提供对重写 URL 和重定向请求的支持。 | 在使用 URL 的组件之前。 |
WebSockets | 启用 WebSockets 协议。 | 在接受 WebSocket 请求所需的组件之前。 |