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

标签 asp.net ajax security asp.net-mvc-2 csrf

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

现在我想阻止页面针对 CSRF。提交表单时,使用 Html.AntiForgeryToken()工作得很好,但是在 AJAX 请求中,我想我将不得不手动附加 token ?有什么开箱即用的东西吗?

我目前的尝试如下所示:

我很想重用现有的魔法。但是,HtmlHelper.GetAntiForgeryTokenAndSetCookie是私有(private)的,我不想在 MVC 中乱搞。另一种选择是编写一个扩展,如

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

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

在这一点上,提出一个本土解决方案似乎更容易,但这确实是重复的代码。

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

最佳答案

您可以使用传统的 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>

然后选择对应的token:
var token = $('#t1 input[name=__RequestVerificationToken]').val();

关于asp.net - 使用 MVC2 的 AJAX 请求中的 CSRF 保护,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2350102/

相关文章:

c# - 如何在 IIS 7 中配置 Http 处理程序?

c# - 从 Javascript 将 KeyValuePair 或 IDictionary 列表传递给 Web Api Controller

ruby-on-rails - Rails 数据库 - 如何使用用户密码存储加密数据?

linux - 如何在代理服务器上反向访问

c# - 基于角色的方法访问

asp.net - 根据 MS Access 查询的结果设置 gridview 列的值

c# - 如何将列表从 View 传递到 Controller ASP.NET MVC5

JavaScript 计算未按预期工作

javascript - 将 AJAX POST 的参数传递给 Grails Controller

javascript - 如何检测ajax加载内容中选择的变化