ASP.net MVC AntiForgeryToken over AJAX

j82*_*749 8 asp.net security ajax asp.net-mvc

我目前正在ASP.net中开发一个MVC应用程序.我正在使用AJAX.ActionLink在记录列表中提供删除链接,但这是非常不安全的.我把这个:

<AcceptVerbs(HttpVerbs.Post)>
Run Code Online (Sandbox Code Playgroud)

在执行删除的功能上,停止仅通过URL调用的功能.但是,仍存在的另一个安全漏洞是,如果我要创建一个包含此内容的基本html页面:

<form action="http://foo.com/user/delete/260" method="post">
<input type="submit" />
</form>
Run Code Online (Sandbox Code Playgroud)

它仍将是一个帖子,但来自不同的位置.

是否可以将AntiForgeryToken与AJAX ActionLink一起使用?如果是这样,这是一种安全的方法吗?我还没有意识到更多的安全漏洞吗?

Ric*_*dOD 9

看看这篇博客文章.

假设您有一个这样的Action方法:

[AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken] public ActionResult DeleteAccount(int accountId) { // delete stuff }

你通过以下方式调用它:

$.post('/home/DeleteAccount', { accountId: 1000 }, function() { alert('Account Deleted.'); });

由于POST不包含AntiForgeryToken,因此会失败.

幸运的是,解决这个问题并不需要太多的智力.AntiForgeryToken的所有客户端组件都将令牌放在一个基本的隐藏字段中.因此,您只需将数据拉出并将其包含在AJAX调用中.

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

$.post('/home/DeleteAccount', { accountId: 1000, '__RequestVerificationToken': token }, function() { alert('Account Deleted.'); });

请注意,如果页面上有多个具有多个AntiForgeryTokens的表单,则必须在jQuery选择器中指定所需的表单.另一个问题是如果你使用jQuery的 serializeArray()函数,你将不得不添加它有点不同:

var formData = $('#myForm').serializeArray(); var token = $('input[name=__RequestVerificationToken]').val(); formData.push({ name: '__RequestVerificationToken', value: token });

$.post('/home/DeleteAccount', formData, function() { alert('Account Deleted.'); });

更新:链接已修复.


小智 6

您可以将AntiForgeryToken与Ajax.ActionLink一起使用,但您需要手动将AntiForgeryToken插入到请求的标题中,如下所示:

function GetAntiForgeryToken(){
   var tokenWindow = window;
   var tokenName = "__RequestVerificationToken";
   var tokenField = $(tokenWindow.document).find("input[type='hidden'][name='" +     tokenName +   "']");
   if (tokenField.length == 0) {return null;}
   else {
      return {
         name: tokenName,
         value: tokenField.val()
      };
   }
};
Run Code Online (Sandbox Code Playgroud)

然后,我们可以使用$ .ajaxPrefilter将其插入标头:

$.ajaxPrefilter(
   function (options, localOptions, jqXHR) {
      var token = GetAntiForgeryToken();
      jqXHR.setRequestHeader(token.name, token.value);
   }
);
Run Code Online (Sandbox Code Playgroud)

在这里写了一篇关于它的帖子.希望这可以帮助!


pip*_*opd 6

将AntiForgeryToken与Ajax.ActionLink一起使用

除了jjwhite01响应; 要在表单数据中插入令牌,请option.data在Prefilter中使用

$.ajaxPrefilter(
    function (options, localOptions, jqXHR) {
        if (options.type !== "GET") {
            var token = GetAntiForgeryToken();
            if (token !== null) {
                if (options.data.indexOf("X-Requested-With") === -1) {
                    options.data = "X-Requested-With=XMLHttpRequest" + (options.data === "") ? "" : "&" + options.data;
                }
                options.data = options.data + "&" + token.name + '=' + token.value;
            }
        }
    }
);
Run Code Online (Sandbox Code Playgroud)


Kei*_*ith 2

我具体不了解 AJAX ActionLink,但可以从 WebForms 页面发布到具有[AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken]属性的 MVC 操作。

您可以使用反射来获取用于设置 cookie 的 MVC 方法以及用于 MVC 验证的匹配表单输入。

请参阅此答案:Using an MVC HtmlHelper from a WebForm