ASP.NET Core防伪令牌:CSRF攻击防护
什么是CSRF攻击?
CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种常见的Web安全威胁,攻击者诱导用户在已认证的Web应用中执行非预期的操作。这种攻击利用了Web应用对用户浏览器的信任机制。
CSRF攻击原理
ASP.NET Core防伪令牌机制
ASP.NET Core提供了内置的防伪令牌(Antiforgery Token)系统来防护CSRF攻击。该系统基于"同步令牌模式"(Synchronizer Token Pattern),通过生成和验证令牌来确保请求的合法性。
防伪令牌工作原理
核心组件与配置
1. 服务注册
在ASP.NET Core中启用防伪令牌系统:
// Program.cs
var builder = WebApplication.CreateBuilder(args);
// 添加防伪服务
builder.Services.AddAntiforgery(options =>
{
options.FormFieldName = "__RequestVerificationToken";
options.HeaderName = "RequestVerificationToken";
options.Cookie.Name = ".AspNetCore.Antiforgery";
options.Cookie.SameSite = SameSiteMode.Strict;
options.Cookie.HttpOnly = true;
});
var app = builder.Build();
// 使用防伪中间件
app.UseAntiforgery();
2. 防伪选项配置
| 配置选项 | 默认值 | 描述 |
|---|---|---|
FormFieldName | __RequestVerificationToken | 表单字段名称 |
HeaderName | RequestVerificationToken | HTTP头名称 |
Cookie.Name | 自动生成 | Cookie名称 |
Cookie.SameSite | SameSiteMode.Strict | SameSite策略 |
Cookie.HttpOnly | true | 是否仅HTTP访问 |
Cookie.SecurePolicy | CookieSecurePolicy.None | 安全策略 |
实现方式
1. 手动令牌管理
app.MapGet("/form", (HttpContext context, IAntiforgery antiforgery) =>
{
var token = antiforgery.GetAndStoreTokens(context);
var html = $"""
<form method="post">
<input name="{token.FormFieldName}" type="hidden" value="{token.RequestToken}" />
<input type="text" name="username" />
<button type="submit">提交</button>
</form>
""";
return Results.Content(html, "text/html");
});
app.MapPost("/submit", async (HttpContext context, IAntiforgery antiforgery) =>
{
try
{
await antiforgery.ValidateRequestAsync(context);
// 验证成功,处理表单数据
return Results.Ok("操作成功");
}
catch (AntiforgeryValidationException)
{
return Results.BadRequest("无效的防伪令牌");
}
});
2. 自动验证属性
ASP.NET Core提供了两种验证属性:
// 单个Action验证
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult UpdateProfile(ProfileModel model)
{
// 只有通过防伪验证的请求才能执行
return View();
}
// 全局自动验证(推荐)
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
3. Razor页面集成
在Razor页面中,防伪令牌自动集成:
@page
@model ContactModel
<form method="post">
<!-- 防伪令牌自动生成 -->
<input type="text" asp-for="Name" />
<button type="submit">提交</button>
</form>
高级配置场景
1. AJAX请求处理
对于AJAX请求,需要手动处理防伪令牌:
// 获取防伪令牌
function getAntiforgeryToken() {
return document.querySelector('input[name="__RequestVerificationToken"]').value;
}
// AJAX请求示例
$.ajax({
url: '/api/data',
type: 'POST',
headers: {
'RequestVerificationToken': getAntiforgeryToken()
},
data: JSON.stringify({}),
contentType: 'application/json'
});
2. API端点保护
[ApiController]
[Route("api/[controller]")]
[AutoValidateAntiforgeryToken]
public class DataController : ControllerBase
{
[HttpPost]
public IActionResult PostData([FromBody] DataModel data)
{
// 自动进行防伪验证
return Ok();
}
}
3. 自定义令牌提供者
public class CustomAntiforgeryAdditionalDataProvider : IAntiforgeryAdditionalDataProvider
{
public string GetAdditionalData(HttpContext context)
{
// 添加自定义数据到令牌
return $"user_{context.User.Identity.Name}";
}
public bool ValidateAdditionalData(HttpContext context, string additionalData)
{
// 验证自定义数据
return additionalData == $"user_{context.User.Identity.Name}";
}
}
// 注册自定义提供者
services.AddAntiforgery(options =>
{
options.AdditionalDataProvider = new CustomAntiforgeryAdditionalDataProvider();
});
安全最佳实践
1. 配置建议
| 安全设置 | 推荐值 | 原因 |
|---|---|---|
| SameSite | Strict | 防止第三方网站发送请求 |
| HttpOnly | true | 防止JavaScript访问Cookie |
| Secure | 根据环境 | 生产环境应设置为true |
| Token过期时间 | 默认 | 保持合理的会话时间 |
2. 防御深度策略
3. 常见陷阱与解决方案
| 问题场景 | 解决方案 |
|---|---|
| AJAX请求失败 | 手动添加防伪令牌到请求头 |
| 文件上传问题 | 确保表单包含enctype="multipart/form-data" |
| 多个表单 | 每个表单都需要独立的防伪令牌 |
| SPA应用 | 使用Token服务提供防伪令牌 |
性能考虑
防伪令牌验证对性能影响极小,但以下情况需要注意:
- 高并发场景:确保防伪服务配置合理
- 分布式部署:所有实例使用相同的机器密钥
- 令牌大小:默认令牌大小约为100字节
故障排除
常见错误及解决方法
// 错误:防伪令牌验证失败
// 解决方案:检查中间件顺序
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseAntiforgery(); // 在认证之后
// 错误:Cookie不被发送
// 解决方案:检查SameSite配置
options.Cookie.SameSite = SameSiteMode.Lax; // 或None(需要Secure)
总结
ASP.NET Core的防伪令牌系统提供了强大而灵活的CSRF防护机制。通过合理配置和使用,可以有效地保护Web应用免受跨站请求伪造攻击。关键要点包括:
- 始终启用防伪保护,特别是对于修改数据的操作
- 使用AutoValidateAntiforgeryTokenAttribute进行全局保护
- 正确配置Cookie安全策略,包括SameSite和HttpOnly
- 为AJAX请求手动处理防伪令牌
- 定期审查和测试防伪配置的有效性
通过遵循这些最佳实践,您可以构建更加安全的ASP.NET Core应用程序,有效防御CSRF攻击威胁。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



