MVC3:HTTP 302重定向错误(由于asp.net认证)

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

我有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)
    {
      ...
    }
}

更新:好的,这与IE9的工作正常,但没有在Chrome(铬引发302)。 FF甚至不提供控制权。

有人知道如何在Chrome和FF的最新版本中实现这一目标吗?


当我尝试使用asp.net mvc3的uploadify时遇到了类似的问题。 经过大量的搜索,这是我发现,似乎工作。 它基本上涉及声明自定义属性,然后将身份验证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);
    }
}

然后声明此Action以将身份验证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的封装器。 我没有修改就复制了我的文件,所以您必须根据您的应用程序进行调整。 需要注意的重要一点是要传递的authCookiescriptData从UploadifyUploadPartial行动通过ViewData的财产。

@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...
    }

最后,要使用我们编写的代码,请在您希望托管Uploadify Widget的任何视图上通过Html.Action Helper调用UploadifyUploadPartial Action:

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

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

链接地址: http://www.djcxy.com/p/71805.html

上一篇: MVC3: HTTP 302 Redirect Error (due to asp.net authentication)

下一篇: Using Identity Foundation with a WCF Web Api