asp.net – 使用MVC2的AJAX请求中的CSRF保护

我正在构建的页面在很大程度上取决于 AJAX.基本上,只有一个页面”,每个数据传输都通过AJAX处理.由于浏览器端的过度优化缓存导致奇怪的问题(数据未重新加载),我必须使用POST执行所有请求(也读取) – 强制重新加载.

现在我想阻止页面反对CSRF.使用表单提交,使用Html.AntiForgeryToken()可以很好地工作,但在AJAX请求中,我想我必须手动附加令牌?有没有开箱即用的东西?

我目前的尝试看起来像这样:

我想重用现有的魔法.但是,HtmlHelper.GetAntiForgeryTokenAndSetCookie是私有的,我不想在MVC中乱砍.另一种选择是写一个类似的扩展名

public static string PlainAntiForgeryToken(this HtmlHelper helper)
{
    // extract the actual field value from the hidden input
    return helper.AntiForgeryToken().DoSomeHackyStringActions();
}

这有点hacky并留下未解决的更大问题:如何验证该令牌?认验证实现是内部的,并且使用表单字段进行硬编码.我试着写一个稍微修改过的ValidateAntiForgeryTokenAttribute,但是它使用了一个私有的AntiForgeryDataSerializer,我真的不想复制它.

在这一点上,似乎更容易想出一个自己开发的解决方案,但这确实是重复的代码.

有什么建议如何以聪明的方式做到这一点?我错过了一些完全明显的东西吗

解决方法

您可以使用传统的Html.AntiForgeryToken()帮助程序在页面的某个位置(不一定在表单内)生成隐藏字段,并将其包含在ajax请求中:
var token = $('input[name=__RequestVerificationToken]').val();
$.post(
    '/SomeAction',{ '__RequestVerificationToken': token },function() {
        alert('Account Deleted.');
    }
);

要在服务器端验证它:

[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
public ActionResult SomeAction() 
{
    return View();
}

如果您的页面上有多个令牌,则可能需要指定要包含的令牌.由于现有的帮助器生成具有相同名称的隐藏字段,因此很难创建一个好的选择器,因此您可以将它们放在跨度中:

<span id="t1"><%= Html.AntiForgeryToken() %></span>
<span id="t2"><%= Html.AntiForgeryToken() %></span>

然后选择相应的令牌:

var token = $('#t1 input[name=__RequestVerificationToken]').val();

相关文章

这篇文章主要讲解了“WPF如何实现带筛选功能的DataGrid”,文...
本篇内容介绍了“基于WPF如何实现3D画廊动画效果”的有关知识...
Some samples are below for ASP.Net web form controls:(fr...
问题描述: 对于未定义为 System.String 的列,唯一有效的值...
最近用到了CalendarExtender,结果不知道为什么发生了错位,...
ASP.NET 2.0 page lifecyle ASP.NET 2.0 event sequence cha...