【问题标题】:Returning File in a site with Authentication在具有身份验证的站点中返回文件
【发布时间】:2013-11-28 08:32:38
【问题描述】:

交叉邮件:https://orchard.codeplex.com/discussions/471384

我正在使用 Orchard CMS 1.7,我们锁定了匿名用户(管理员 -> 用户 -> 角色 -> 取消选中站点前端)的整个站点。现在,每个页面或文件都要求人们在访问之前进行身份验证。

现在,我们正在尝试提供一些文件可供下载的选项,具体取决于特定内容类型中的字段。

问题

当我在通过身份验证时下载文件时,我可以毫无问题地获得它。如果我是匿名的,我会得到文件(正确的文件名和类型),但它没有内容和大小(0 字节)。我很确定这是一个身份验证问题,因为当我启用对站点前端的匿名访问时,它一切正常。

这是返回文件的实际代码(redirectLink是文件路径):

                    var cd = new System.Net.Mime.ContentDisposition
                    {
                        FileName = fileName,
                        Inline = false
                    };

                    Response.AppendHeader("Content-Disposition", cd.ToString());
                    return File(HttpUtility.UrlDecode(redirectLink), mimeType);

这是我的完整代码(控制器动作):

        [AlwaysAccessible]
        public ActionResult Download(int resourceId)
        {
            //set default unsecure value to false
            bool isUnsecured = false;

            var resourceItem = ContentManager.Get(resourceId);
            if (resourceItem == null || resourceItem.ContentType != "Resource")
            {
                // TODO: log that ID not found??
                return new HttpStatusCodeResult(HttpStatusCode.NotFound);
            }

            var resourcePart = resourceItem.Parts.FirstOrDefault(p => p.PartDefinition.Name == resourceItem.ContentType);

            //retrieve unsecure boolean
            if (resourcePart != null)
            {
                var unsecuredField = resourcePart.Fields.FirstOrDefault(f => f.Name == "Unsecured");
                if (unsecuredField != null)
                {
                    isUnsecured = unsecuredField.Storage.Get<bool>();
                }
            }

            //check if unsecured resource / allow anonymous downloads
            //see Orchard.Security.SecurityFilter - I'm not sure where this is actually used in Orchard though...
            if (!isUnsecured && !Services.Authorizer.Authorize(StandardPermissions.AccessFrontEnd, T("Unauthenticated")))
            {
                return new HttpUnauthorizedResult(); 
            }                                     

            if (resourcePart != null)
            {
                // TODO: Potential concurrency issues?
                var downloadCountPart = resourcePart.As<DownloadCountPart>();
                if (downloadCountPart != null)
                {
                    downloadCountPart.Total++;
                    ContentManager.Publish(resourceItem);
                }

                // Do the redirection/serving of item!
                // Prioritize link field over resource field, according to the UI
                var linkedField = resourcePart.Fields.FirstOrDefault(f => f.Name == "LinkedFile");
                if (linkedField != null)
                {
                    var redirectLink = linkedField.Storage.Get<string>();
                    if (redirectLink != null)
                    {
                        return Redirect(redirectLink);
                    }
                }

                var resourceField = resourcePart.Fields.First(f => f.Name == "ResourceFile");
                if (resourceField != null)
                {
                    var resourceMPF = (resourceField as MediaLibraryPickerField);     

                    if (resourceMPF != null && resourceMPF.MediaParts != null && resourceMPF.MediaParts.Count() > 0)
                    {
                        var fileName = resourceMPF.MediaParts.First().FileName;
                        var mimeType = resourceMPF.MediaParts.First().MimeType;
                        var redirectLink = resourceMPF.MediaParts.First().MediaUrl;       //to check: first? when are there multiple?
                        if(!string.IsNullOrWhiteSpace(redirectLink))
                        {

                            var cd = new System.Net.Mime.ContentDisposition
                            {
                                FileName = fileName,
                                Inline = false
                            };

                            Response.AppendHeader("Content-Disposition", cd.ToString());
                            return File(HttpUtility.UrlDecode(redirectLink), mimeType);
                        }

                    }                   
                }
            }

            return new HttpStatusCodeResult(HttpStatusCode.NotFound);
        }

这让我想到了这些问题:

  1. 带有返回文件的事件,它仍然考虑到当前用户 该人是否经过身份验证?
  2. 我可以使用模拟来绕过这个问题吗?

我们将不胜感激任何建议或信息。谢谢!

【问题讨论】:

    标签: file asp.net-mvc-4 orchardcms orchardcms-1.7


    【解决方案1】:

    您得到空文件的原因是输出缓存模块中的一个错误,该错误仅对匿名用户有效。此错误已在 Orchard 1.7.2 中修复,因此升级会有所帮助。

    此外,由于主要是经过身份验证的用户使用您的网站,因此您并没有真正使用输出缓存作为临时解决方法,您可以在升级之前禁用该模块(我的建议是,因为此类匿名文件下载可以缓存以获得更好的性能)。

    【讨论】:

    • 工作得很好,虽然它没有立即反映。我继续删除了缓存.dat 和 App_Data 中的其他内容,请务必确定。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    相关资源
    最近更新 更多