0

交叉邮件: 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. 我可以使用模拟来绕过这个问题吗?

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

4

1 回答 1

1

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

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

于 2013-11-28T11:43:17.983 回答