ASP.NET Core 防伪机制 Anti-Forgery 解析:从原理到实战应用
2025-11-14 211 0
什么是防伪机制(Anti-Forgery)?
在 Web 应用中,常见的攻击之一是 跨站请求伪造(CSRF/XSRF),即攻击者利用用户已登录的状态,通过用户浏览器发起未经授权的请求。为防止此类攻击, ASP.NET Core 内建了防伪(Anti-Forgery)机制:服务器为合法页面生成一个“令牌(token)”,客户端提交表单或 AJAX 时必须带上该令牌,服务器验证令牌与用户/会话是否匹配,若不匹配则拒绝请求。
ASP.NET Core 中防伪机制的工作原理
-
当用户访问一个产生表单提交的页面时,系统会生成两个部分:
-
一个存储在 Cookie 中的令牌
-
一个随表单(或请求头)发送的令牌
-
-
当客户端提交 POST 等修改状态的请求时,服务器验证这两者是否匹配、是否属于同一用户/会话。若验证失败,则抛出异常或返回 400 错误。
-
在 MVC/Razor Pages 模板中,使用
<form method="post">时,默认会自动在表单中插入隐藏字段(如__RequestVerificationToken)。开发者也可手动使用@Html.AntiForgeryToken()。 -
系统通过内置的服务(如 IAntiforgery 接口)来生成并验证令牌。
默认行为与配置要点
-
在 ASP.NET Core 中,只要调用
AddMvc()、MapRazorPages()、MapControllerRoute()等 API,防伪服务就被加入到 DI 容器中。 -
对于使用 Tag Helper 的
<form method="post">,系统默认生成隐藏字段令牌;如通过纯 HTML 表单或自定义方式,则需手动加入。 -
可通过
builder.Services.AddAntiforgery(options => { ... })来自定义令牌名称、Cookie 名称、Header 名称等:例如options.Cookie.Name、options.FormFieldName、options.HeaderName。 -
可全局启用验证过滤器:
services.AddControllersWithViews(options => { options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); });这样对于所有 POST/PUT/PATCH/DELETE 请求会自动做令牌校验。
-
若项目部署在多服务器(Server Farm)环境,则需为数据保护(DataProtection)配置共享密钥存储,以保证令牌生成/验证在所有实例间一致。
在 MVC、Razor Pages、Minimal APIs 中的应用
MVC + Razor Pages
-
在视图中使用
<form asp-action="…">时,默认会生成防伪隐藏字段。 -
在 Controller 的 POST 方法上可使用
[ValidateAntiForgeryToken]属性强制验证。 -
若希望全局应用可使用
[AutoValidateAntiforgeryToken]。 -
若某些情况不需要验证可标记
[IgnoreAntiforgeryToken]。
Minimal APIs
-
对于没有 MVC 模型绑定的简化 API,需要手动注入
IAntiforgery服务。 -
在
Program.cs中:builder.Services.AddAntiforgery(); var app = builder.Build(); app.MapPost("/save", async (HttpContext context, IAntiforgery antiforgery) => { await antiforgery.ValidateRequestAsync(context); // …处理业务 }); -
对于通过 JavaScript 发起的请求,需从页面获取令牌并将其作为请求头或请求体参数发送。
实战场景与注意事项
-
AJAX 请求:当使用 Fetch、XHR 或 SPA 框架(如 React/Vue)发起非表单提交时,必须将防伪令牌放在请求头或请求体中。
-
Cookie 设置:配合 SameSite 属性(如 Lax、Strict)可进一步增强安全。
-
登录/登出后令牌失效:令牌与认证用户有关,若用户发生登录状态变化,应更新或失效。
-
服务器集群环境:确保所有实例都共享 DataProtection 密钥,否则令牌在某些实例上可能无法验证。
-
只读请求不需防伪:GET、HEAD、OPTIONS、TRACE 通常不改变状态,一般无需防伪验证。
-
API 场景:如果后端使用 Cookie 认证,则仍需防伪;若改用 JWT 或其他无状态机制,CSRF 风险相对较低。
总结
防伪机制是 ASP.NET Core 在 Web 安全中不可或缺的一环。通过理解其原理、掌握默认行为及配置方式,并在 MVC、Razor Pages、Minimal API 中正确应用,开发者可以显著提升应用抵御 CSRF 攻击的能力。推荐将防伪验证作为默认启用、不轻易禁用,并结合其他安全措施(如 SameSite Cookie、严格认证流程)共同构筑安全防线。