我已经在我的应用程序中实现了对CSRF攻击的缓解,这是我在互联网上的一些博客文章上读到的信息。特别是这些帖子一直是我实现的驱动力

ASP的最佳实践。NET MVC从ASP。NET和Web工具开发人员内容团队 跨站点请求伪造攻击的剖析,来自Phil Haack的博客 ASP中的AntiForgeryToken。NET MVC框架- Html。来自David Hayden博客的AntiForgeryToken和ValidateAntiForgeryToken属性

基本上,这些文章和建议说,为了防止CSRF攻击,任何人都应该实现以下代码:

在接受POST Http谓词的每个操作上添加[ValidateAntiForgeryToken] (HttpPost) (ValidateAntiForgeryToken) SomeAction(SomeModel模型){ } 在向服务器提交数据的表单中添加<%= Html.AntiForgeryToken() %> helper

无论如何,在我的应用程序的某些部分,我做Ajax post与jQuery到服务器没有任何形式。例如,当我让用户点击图像来执行特定操作时就会发生这种情况。

假设我有一个包含活动列表的表。我在表的一列上有一个图像,说“标记活动已完成”,当用户单击该活动时,我正在做Ajax POST如下示例:

$("a.markAsDone").click(function (event) {
    event.preventDefault();
    $.ajax({
        type: "post",
        dataType: "html",
        url: $(this).attr("rel"),
        data: {},
        success: function (response) {
            // ....
        }
    });
});

在这些情况下,我如何使用<%= Html.AntiForgeryToken() %> ?我是否应该在Ajax调用的数据参数中包含helper调用?

很抱歉写了这么长时间,非常感谢你的帮助

编辑:

根据jayrdub的回答,我用下面的方式

$("a.markAsDone").click(function (event) {
    event.preventDefault();
    $.ajax({
        type: "post",
        dataType: "html",
        url: $(this).attr("rel"),
        data: {
            AddAntiForgeryToken({}),
            id: parseInt($(this).attr("title"))
        },
        success: function (response) {
            // ....
        }
    });
});

当前回答

AntiforgeryToken仍然是一个痛苦,上面的例子对我来说没有一个是逐字逐句的。那里的人太多了。所以我把它们结合起来。需要一个@Html。在iirc周围悬挂的表单中的防伪造令牌

解决方法如下:

function Forgizzle(eggs) {
    eggs.__RequestVerificationToken =  $($("input[name=__RequestVerificationToken]")[0]).val();
    return eggs;
}

$.ajax({
            url: url,
            type: 'post',
            data: Forgizzle({ id: id, sweets: milkway }),
});

当有疑问时,添加更多的$符号

其他回答

我知道这个问题发布已经有一段时间了,但我发现了非常有用的资源,其中讨论了AntiForgeryToken的用法,并使其使用起来不那么麻烦。它还提供了jquery插件,可以轻松地在AJAX调用中包含防伪造令牌:

ASP的防伪请求配方。NET MVC和AJAX

我的贡献不大,但也许有人会觉得它有用。

我使用ajax post来运行一个删除方法(碰巧是从一个visjs时间轴,但这是不相关的)。这就是我所说的:

这是Index.cshtml

@Scripts.Render("~/bundles/schedule")
@Styles.Render("~/bundles/visjs")
@Html.AntiForgeryToken()

<!-- div to attach schedule to -->
<div id='schedule'></div>

<!-- div to attach popups to -->
<div id='dialog-popup'></div>

我在这里只添加了@Html.AntiForgeryToken(),以使令牌出现在页面中

然后在我的ajax帖子中,我使用:

$.ajax(
    {
        type: 'POST',
        url: '/ScheduleWorks/Delete/' + item.id,
        data: {
            '__RequestVerificationToken': 
            $("input[name='__RequestVerificationToken']").val()
              }
     }
);

它将从页面上抓取的令牌值添加到发布的字段中

在此之前,我尝试将值放在头文件中,但我得到了相同的错误

请随意发布改进。这似乎是一种我能理解的简单方法

我使用了一个简单的js函数

AddAntiForgeryToken = function(data) {
    data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
    return data;
};

由于页面上的每个表单都有相同的令牌值,所以只需在最顶部的母版页中添加如下内容即可

<%-- used for ajax in AddAntiForgeryToken() --%>
<form id="__AjaxAntiForgeryForm" action="#" method="post"><%= Html.AntiForgeryToken()%></form>  

然后在ajax调用do(编辑以匹配第二个示例)

$.ajax({
    type: "post",
    dataType: "html",
    url: $(this).attr("rel"),
    data: AddAntiForgeryToken({ id: parseInt($(this).attr("title")) }),
    success: function (response) {
        // ....
    }
});

我只是在我当前的项目中实现了这个实际问题。我做的所有ajax- post,需要一个认证用户。

首先,我决定钩我的jquery ajax调用,所以我不重复自己太频繁。这个javascript代码片段确保所有ajax (post)调用都会将我的请求验证令牌添加到请求中。注意:名字__RequestVerificationToken是由. net框架使用的,所以我可以利用标准的Anti-CSRF特性,如下所示。

$(document).ready(function () {
    var securityToken = $('[name=__RequestVerificationToken]').val();
    $('body').bind('ajaxSend', function (elm, xhr, s) {
        if (s.type == 'POST' && typeof securityToken != 'undefined') {
            if (s.data.length > 0) {
                s.data += "&__RequestVerificationToken=" + encodeURIComponent(securityToken);
            }
            else {
                s.data = "__RequestVerificationToken=" + encodeURIComponent(securityToken);
            }
        }
    });
});

在你的视图中,你需要令牌对上面的javascript可用,只需使用通用的HTML-Helper。基本上,您可以在任何需要的地方添加此代码。我把它放在if(Request.IsAuthenticated)语句中:

@Html.AntiForgeryToken() // you can provide a string as salt when needed which needs to match the one on the controller

在你的控制器中简单地使用标准的ASP。Net MVC Anti-CSRF机制。我是这样做的(尽管我实际上使用了Salt)。

[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public JsonResult SomeMethod(string param)
{
    // do something
    return Json(true);
}

使用Firebug或类似的工具,你可以很容易地看到你的POST请求现在有一个__RequestVerificationToken参数附加。

这是我见过的最简单的方法。注意:确保在视图中有“@Html.AntiForgeryToken()”

  $("a.markAsDone").click(function (event) {
        event.preventDefault();
        var sToken = document.getElementsByName("__RequestVerificationToken")[0].value;
        $.ajax({
            url: $(this).attr("rel"),
            type: "POST",
            contentType: "application/x-www-form-urlencoded",
            data: { '__RequestVerificationToken': sToken, 'id': parseInt($(this).attr("title")) }
        })
        .done(function (data) {
            //Process MVC Data here
        })
        .fail(function (jqXHR, textStatus, errorThrown) {
            //Process Failure here
        });
    });