前段时间我在使用Uploadify插件时出现问题,我确实找到了此answer中描述的解决方案。
该问题的问题主要是由于Uploadify使用flash插件而flash插件不与服务器端代码共享身份验证cookie。
解决方案是使用Authorize属性的自定义版本(代码在该答案中发布)。
属性[TokenizedAuthorize]被放置在控制器类上,如下所示
[TokenizedAuthorize]
[CheckForActiveService]
public partial class DocumentController : BaseController
{
}
前几天我在表单中添加了<%: Html.AntiForgeryToken() %>
和
[ValidateAntiForgeryToken]
操作方法,如下例所示:
[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult Upload( HttpPostedFileBase fileData ) {
}
无论如何,我不再能够将文件上传到服务器了。使用调试器,我可以在TokenizedAuthorize
代码
return base.AuthorizeCore( httpContext );
我得到Elmah处理的异常
System.Web.Mvc.HttpAntiForgeryException: invalid or not specified anti forgery token
in System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization(AuthorizationContext filterContext)
in System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor)
in System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
此异常似乎确认正在调用[ValidateAntiForgeryToken]
属性...但我无法理解代码的问题在哪里。
任何帮助?
修改:
使用调试器我已经检查了__RequestVerificationToken
表单参数的值,正如您所看到的,它已使用<%: Html.AntiForgeryToken() %>
编辑2 :
如果我对Post Action上的[ValidateAntiForgeryToken]
发表评论,我也可以确认一下
一切都按预期工作
编辑3 :
由于post函数是由uploadify插件完成的ajax调用,因此使用小js函数将AntiForgeryToken添加到post参数中,如下面的代码所示
$('#fileInput').uploadify({
//other uploadify parameters removed for brevity
scriptData: AddAntiForgeryToken({ AuthenticationToken: auth }),
});
其中AddAntiForgeryToken()
是我的母版页中定义的javascript函数,用于支持服务器上的所有ajax帖子
<%-- used for ajax in AddAntiForgeryToken() --%>
<form id="__AjaxAntiForgeryForm" action="#" method="post">
<%: Html.AntiForgeryToken() %>
</form>
// Encapsulate the Anti Forgery Token fetching
AddAntiForgeryToken = function (data) {
data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
return data;
};
编辑4 :
Darin直觉是正确的。 Uploadify脚本不向服务器发送任何cookie,因此服务器无法验证AntiForgeryToken。如何在Uploadify scriptData部分中添加cookie?
答案 0 :(得分:1)
您必须确保在请求中发送与__RequestVerificationToken
字段具有相同值的Cookie。通常,此cookie由Html.AntiforgeryToken()
发出,并且必须在服务器上完成,因为其值是使用服务器计算机密钥加密的。如果请求是由Flash客户端执行的,我不知道它是否发送cookie。如果不是这种情况,则需要手动发送。
还有一些你应该知道的东西,虽然我不认为它适用于你的情况但值得检查,但它会抛出相同的异常。当您使用Html.AntiforgeryToken()
帮助程序时,如果有登录用户,则他的用户名是发出的cookie的一部分。如果您尝试POST到使用[ValidateAntiForgeryToken]
修饰的控制器操作,它将验证当前登录的用户是否与发出cookie时的用户相同,如果不是,则会抛出此异常。所以我看到的是人们使用Html.AntiforgeryToken()
生成一些html表单作为匿名用户,然后使用AJAX登录用户,一旦登录用户提交表单 - 它将失败。