2009-08-28 58 views
8

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

<AcceptVerbs(HttpVerbs.Post)> 

在功能上做删除,它停止简单地通过一个URL调用的函数。但是,仍然存在其他安全漏洞是,如果我是做一个基本的HTML页面与此内容:

<form action="http://foo.com/user/delete/260" method="post"> 
<input type="submit" /> 
</form> 

它仍然会perfoming一个帖子,而是从不同的位置。

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

回答

2

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

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

看到这个答案:Using an MVC HtmlHelper from a WebForm

9

看看这个blog post

假设你有一个操作方法类似 这样的:

[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.'); });

更新:链接已定。

+1

该链接的死 – Keith 2010-04-01 09:08:29

+0

你不需要formData.push({名称:“__RequestVerificationToken”,值:令牌});因为serializeArray()将返回表单中的所有输入,其中包括__RequestVerificationToken隐藏字段。 – 2011-08-25 06:44:08

+0

是的,你确实需要这个AJAX帖子(使用当前的MVC 4和MS unobtrusive AJAX = jQuery)! – 2013-02-04 16:09:01

0

我自己并没有使用任何ajax帮助程序,但我看不到任何原因导致您无法使用链接。就我个人而言,我会使用onload事件处理程序不显眼地从表单本身创建一个链接,然后删除表单。

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() 
     }; 
    } 
}; 

然后,我们可以使用$ .ajaxPrefilter将其插入到页眉:

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

我写了一篇关于它here一个职位。希望这可以帮助!

+0

这确实在标题中发送了令牌,但[Form ValidateAntiForgeryToken]过滤器要求在Form数据中使用这个... – iGanja 2013-05-04 00:23:24

6

使用AntiForgeryToken与Ajax.ActionLink

除了jjwhite01响应; 插入表格的数据令牌,在预过滤器使用option.data

$.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; 
      } 
     } 
    } 
); 
+1

MVC 4中的不显眼的ajax脚本包括 - options.data.push({name:“X-Requested-With “,value:”XMLHttpRequest“}) - 因此现在不需要检查和添加 – Brent 2013-06-11 09:19:15