【问题标题】:Uploadify - MVC3: HTTP 302 Redirect Error (due to asp.net authentication)Uploadify - MVC3:HTTP 302 重定向错误(由于 asp.net 身份验证)
【发布时间】:2012-04-15 00:44:46
【问题描述】:

我正在使用 uploadify 批量上传文件,但出现 302 重定向错误。我假设这是因为脚本调用中没有传回一些 asp.net 身份验证 cookie 令牌。

我已经在常规的裸机 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)
    {
      ...
    }
}

更新:好的,这适用于 IE9,但不适用于 Chrome(Chrome 会抛出 302)。 FF 甚至不渲染控件。

有谁知道如何在最新的转速下让它工作 Chrome 和 FF?

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-mvc-3 uploadify


    【解决方案1】:

    当我尝试将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 操作中的 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>
    

    对于将帖子上传到的操作,使用新的 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.Action Helper 在您希望托管 Uploadify Widget 的任何 View 上调用 UploadifyUploadPartial Action:

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

    此时您应该很高兴。该代码应该可以在 FF、Chrome 和 IE 9 中运行。如果您有问题,请告诉我。

    【讨论】:

    • 嗨,我已经尝试重新审视这个,我确实找到了类似于 tokenizeauthorize 属性的东西。但是,仍然没有在请求标头中设置 Cookie:(这是 IE9 标头请求中的内容)当然,Chrome 缺少它,FF 甚至无法与 uploadify 一起使用。饼干:__RequestVerificationToken_Lw __ = 8 + WZPGAaKtgkIPfbBovP1ZRP2qQKE3u67ueltnzcoCPH0nN1tUHdtgUorjlweUvn + zTJhkFeRuMShCOrbyHR5Xi3DOL4HCspXuVEOsWIr4Ape + l5MYPiFsQ6Lnw8LstqNjceWW9EaV24eA0mVxq2xTG18h / INNKLB8cRUiEn9DI =; .ASPXAUTH=C64A69436A8F...
    • 我也见过这个解决方案,但它没有将 Cookie: __RequestVerificationToken... 放在标题中,因此永远不会调用 Upload 操作。这只是 Chrome 的问题(FF 甚至不加载控件,IE9 工作正常)。
    • protected override bool AuthorizeCore(HttpContextBase httpContext) { string token = httpContext.Request.Params[TOKEN_KEY]; if (token != null) token 在这段代码中始终为空
    • @JaJ 嘿,看来我没有在我的解决方案中发布所有内容,因为我最终没有使用 Uploadify(即使我让它工作了)我对代码有点生疏了。让我用缺少的东西更新我的答案。
    • 酷代码!但 FF 不呈现控件。它应该显示的地方完全是空白的。 IE9 和 Chrome 渲染良好。
    猜你喜欢
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    • 2011-11-21
    • 2017-05-23
    • 2016-04-02
    • 1970-01-01
    • 2016-03-10
    • 2011-06-05
    相关资源
    最近更新 更多