2012-04-15 233 views
3

我正在使用uploadify来批量上传文件,并且出现302重定向错误。我假设这是因为一些asp.net身份验证cookie令牌没有在脚本调用中传回。Uploadify - MVC3:HTTP 302重定向错误(由于asp.net认证)

我有uploadify工作在一个普通的骨胳mvc3应用程序,但是当我试图将它集成到一个安全的asp.net mvc3应用程序时,它试图重定向到帐户/登录。

我有一个认证令牌(@auth),它在视图内以长字符串的形式返回,但我仍然得到302重定向错误。

任何想法如何发送cookie身份验证数据?

查看:

@{ 
    string auth = @Request.Cookies[FormsAuthentication.FormsCookieName] == null ? string.Empty : Request.Cookies[FormsAuthentication.FormsCookieName].Value; 
    } 


<script type="text/javascript"> 
    jQuery.noConflict(); 
    jQuery(document).ready(function() { 
     jQuery("#bulkupload").uploadify({ 
      'uploader': '@Url.Content("~/Scripts/uploadify.swf")', 
      'cancelImg': '/Content/themes/base/images/cancel.png', 
      'buttonText': 'Browse Files', 
      'script': '/Creative/Upload/', 
      scriptData: { token: "@auth" }, 
      'folder': '/uploads', 
      'fileDesc': 'Image Files', 
      'fileExt': '*.jpg;*.jpeg;*.gif;*.png', 
      'sizeLimit': '38000', 
      'multi': true, 
      'auto': true, 
       'onError'  : function (event,ID,fileObj,errorObj) { 
     alert(errorObj.type + ' Error: ' + errorObj.info); 
    } 
     }); 
    }); 
    </script> 

控制器:

public class CreativeController : Controller 
{ 
    public string Upload(HttpPostedFileBase fileData, string token) 
    { 
     ... 
    } 
} 

UPDATE:好吧,这正常工作与IE9,但无法在Chrome(谷歌浏览抛出302)。 FF甚至不提供控制权。

是否有人知道如何在Chrome和FF的最新转换版本中获得此工作的 ?

回答

5

当我尝试将uploadify与asp.net mvc3结合使用时,我遇到了类似的问题。经过大量的搜索,这是我发现,似乎工作。它基本上涉及声明自定义属性,然后将身份验证Cookie显式传递到Uploadify的HTTP Post并通过自定义属性手动处理Cookie。

首先声明这个自定义属性:

/// <summary> 
/// A custom version of the <see cref="AuthorizeAttribute"/> that supports working 
/// around a cookie/session bug in Flash. 
/// </summary> 
/// <remarks> 
/// Details of the bug and workaround can be found on this blog: 
/// http://geekswithblogs.net/apopovsky/archive/2009/05/06/working-around-flash-cookie-bug-in-asp.net-mvc.aspx 
/// </remarks> 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 
public class TokenizedAuthorizeAttribute : AuthorizeAttribute 
{ 
    /// <summary> 
    /// The key to the authentication token that should be submitted somewhere in the request. 
    /// </summary> 
    private const string TOKEN_KEY = "authCookie"; 

    /// <summary> 
    /// This changes the behavior of AuthorizeCore so that it will only authorize 
    /// users if a valid token is submitted with the request. 
    /// </summary> 
    /// <param name="httpContext"></param> 
    /// <returns></returns> 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     string token = httpContext.Request.Params[TOKEN_KEY]; 

     if (token != null) 
     { 
      FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(token); 

      if (ticket != null) 
      { 
       var identity = new FormsIdentity(ticket); 
       string[] roles = System.Web.Security.Roles.GetRolesForUser(identity.Name); 
       var principal = new GenericPrincipal(identity, roles); 
       httpContext.User = principal; 
      } 
     } 

     return base.AuthorizeCore(httpContext); 
    } 
} 

然后宣布这个行动身份验证Cookie传递到你的ViewData的,所以你可以将它传递给Uploadify部件。这也将是您稍后调用Uploadify小部件时所调用的操作。

[Authorize] 
    public ActionResult UploadifyUploadPartial() 
    { 
     ViewBag.AuthCookie = Request.Cookies[FormsAuthentication.FormsCookieName] == null 
           ? string.Empty 
           : Request.Cookies[FormsAuthentication.FormsCookieName].Value; 
     return PartialView("UploadifyUpload"); 
    } 

这是UploadifyUpload查看代码。它基本上是设置Uploadify的JavaScript的封装器。我没有修改就复制了我的文件,所以您必须根据您的应用程序进行调整。需要注意的重要一点是,您需要通过UploadifyUploadPartial Action的ViewData将authCookie传递给scriptData属性。

@if (false) 
{ 
    <script src="../../Scripts/jquery-1.5.1-vsdoc.js" type="text/javascript"></script> 
} 
@{ 
    ViewBag.Title = "Uploadify"; 
} 
<script src="@Url.Content("~/Scripts/plugins/uploadify/swfobject.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/plugins/uploadify/jquery.uploadify.v2.1.4.min.js")" type="text/javascript"></script> 
<link href="@Url.Content("~/Scripts/plugins/uploadify/uploadify.css")" rel="stylesheet" type="text/css" /> 
<script> 
    $(document).ready(function() { 
     CreateUploadifyInstance("dir-0"); 
    }); 
    function CreateUploadifyInstance(destDirId) { 
     var uploader = "@Url.Content("~/Scripts/plugins/uploadify/uploadify.swf")"; 
     var cancelImg = "@Url.Content("~/Scripts/plugins/uploadify/cancel.png")"; 
     var uploadScript = "@Url.Content("~/Upload/UploadifyUpload")"; 
     var authCookie = "@ViewBag.AuthCookie"; 
     $('#uploadifyHiddenDummy').after('<div id="uploadifyFileUpload"></div>'); 
     $("#uploadifyFileUpload").uploadify({ 
      'uploader': uploader, 
      'cancelImg': cancelImg, 
      'displayData': 'percentage', 
      'buttonText': 'Select Session...', 
      'script': uploadScript, 
      'folder': '/uploads', 
      'fileDesc': 'SunEye Session Files', 
      'fileExt': '*.son2', 
      'scriptData' : {'destDirId':destDirId, 'authCookie': authCookie}, 
      'multi': false, 
      'auto': true, 
      'onCancel': function(event, ID, fileObj, data) { 
       //alert('The upload of ' + ID + ' has been canceled!'); 
      }, 
      'onError': function(event, ID, fileObj, errorObj) { 
       alert(errorObj.type + ' Error: ' + errorObj.info); 
      }, 
      'onAllComplete': function(event, data) { 
       $("#treeHost").jstree("refresh"); 
       //alert(data.filesUploaded + ' ' + data.errors); 
      }, 
      'onComplete': function(event, ID, fileObj, response, data) { 
       alert(ID + " " + response); 
      } 
     }); 
    } 
    function DestroyUploadifyInstance() { 
     $("#uploadifyFileUpload").unbind("uploadifySelect"); 
     swfobject.removeSWF('uploadifyFileUploadUploader'); 
     $('#uploadifyFileUploadQueue').remove(); 
     $('#uploadifyFileUploadUploader').remove(); 
     $('#uploadifyFileUpload').remove(); 
    } 
</script> 
<div id="uploadifyHiddenDummy" style="visibility:hidden"></div> 
<div id="uploadifyFileUpload"> 
</div> 

为了您的行动,Uploadify帖子来,使用新的TokenizedAuthorize属性,而不是Authorize属性:

[HttpPost] 
    [TokenizedAuthorize] 
    public string UploadifyUpload(HttpPostedFileBase fileData) 
    { 
     FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(Request.Form["authCookie"]); 
     if (ticket != null) 
     { 
      var identity = new FormsIdentity(ticket); 
      if (!identity.IsAuthenticated) 
      { 
       return "Not Authenticated"; 
      } 
     } 
     // Now parse fileData... 
    } 

最后,使用我们所编写的代码,通过HTML调用UploadifyUploadPartial行动.Action Helper任何查看你想要承载的Uploadify小工具:

@Html.Action("UploadifyUploadPartial", "YourUploadControllerName") 

你应该很好去这一点。该代码应该在FF,Chrome和IE 9中运行。让我知道你是否有问题。

+0

嗨,我已经尝试重温这个,我找到了类似于tokenizeauthorize属性的东西。然而,Cookie仍然没有在请求标头中设置: (这是什么起床的IE9的标题请求)当然,它缺少的Chrome和FF甚至不能使用uploadify。 曲奇:__RequestVerificationToken_Lw __ = 8 + WZPGAaKtgkIPfbBovP1ZRP2qQKE3u67ueltnzcoCPH0nN1tUHdtgUorjlweUvn + zTJhkFeRuMShCOrbyHR5Xi3DOL4HCspXuVEOsWIr4Ape + l5MYPiFsQ6Lnw8LstqNjceWW9EaV24eA0mVxq2xTG18h/INNKLB8cRUiEn9DI =; .ASPXAUTH = C64A69436A8F ... – JaJ 2012-04-20 21:19:02

+0

我也看到了这个解决方案,但它并没有将Cookie:__RequestVerificationToken ...放在标题中,所以上传操作永远不会被调用。这只是Chrome的一个问题(FF甚至没有加载控件,IE9工作正常)。 – JaJ 2012-04-23 21:42:03

+0

protected override bool AuthorizeCore(HttpContextBase httpContext) { string token = httpContext.Request.Params [TOKEN_KEY]; 如果(令牌!= null) 令牌在此代码中始终为空 – JaJ 2012-04-23 21:57:08