我已经在我的应用程序中实现了对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) {
            // ....
        }
    });
});

当前回答

function DeletePersonel(id) {

    var data = new FormData();
    data.append("__RequestVerificationToken", "@HtmlHelper.GetAntiForgeryToken()");

    $.ajax({
        type: 'POST',
        url: '/Personel/Delete/' + id,
        data: data,
        cache: false,
        processData: false,
        contentType: false,
        success: function (result) {
        }
    });
}

public static class HtmlHelper {
    public static string GetAntiForgeryToken() {
        System.Text.RegularExpressions.Match value = 
                System.Text.RegularExpressions.Regex.Match(System.Web.Helpers.AntiForgery.GetHtml().ToString(), 
                        "(?:value=\")(.*)(?:\")");
        if (value.Success) {
            return value.Groups[1].Value;
        }
        return "";
    }
}

其他回答

发现这个非常聪明的想法从https://gist.github.com/scottrippey/3428114为每$。Ajax调用它,修改请求并添加令牌。

// Setup CSRF safety for AJAX:
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    if (options.type.toUpperCase() === "POST") {
        // We need to add the verificationToken to all POSTs
        var token = $("input[name^=__RequestVerificationToken]").first();
        if (!token.length) return;

        var tokenName = token.attr("name");

        // If the data is JSON, then we need to put the token in the QueryString:
        if (options.contentType.indexOf('application/json') === 0) {
            // Add the token to the URL, because we can't add it to the JSON data:
            options.url += ((options.url.indexOf("?") === -1) ? "?" : "&") + token.serialize();
        } else if (typeof options.data === 'string' && options.data.indexOf(tokenName) === -1) {
            // Append to the data string:
            options.data += (options.data ? "&" : "") + token.serialize();
        }
    }
});

不要使用Html.AntiForgeryToken。相反,使用反伪造技术。GetTokens和AntiForgery。在ASP中防止跨站请求伪造(CSRF)攻击中描述的从Web API验证。NET MVC应用程序。

你也可以这样做:

$("a.markAsDone").click(function (event) {
    event.preventDefault();

    $.ajax({
        type: "post",
        dataType: "html",
        url: $(this).attr("rel"),
        data: $('<form>@Html.AntiForgeryToken()</form>').serialize(),
        success: function (response) {
        // ....
        }
    });
});

这是使用Razor,但如果您使用WebForms语法,您也可以使用<%= %>标记

首先在html中使用@Html.AntiForgeryToken()

 $.ajax({
        url: "@Url.Action("SomeMethod", "SomeController")",
        type: 'POST',
        data: JSON.stringify(jsonObject),
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        async: false,
        beforeSend: function (request) {
            request.setRequestHeader("RequestVerificationToken", $("[name='__RequestVerificationToken']").val());
        },
        success: function (msg) {
            alert(msg);
        }

对360Airwalk解决方案略有改进。这将在javascript函数中嵌入防伪造令牌,因此@Html.AntiForgeryToken()不再需要包含在每个视图中。

$(document).ready(function () {
    var securityToken = $('@Html.AntiForgeryToken()').attr('value');
    $('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);
            }
        }
    });
});