【问题标题】:Download Private Blob Image using Proxy?使用代理下载私有 Blob 图像?
【发布时间】:2016-08-14 02:30:00
【问题描述】:

我目前通过 public blob url 访问我网站上的图片:

https://subscription_name.blob.core.windows.net/users/5/drivers_licence.jpg

我想将 blob 访问从公共更改为 private 并将网址访问为:

http://localhost:3000/users/5/drivers_licence.jpg

Blob Url 已存储并从数据库中提取,因此我可以运行查询以使用新前缀(本地主机之一)更新所有记录,这很简单。

问题是:如何实现代理,以便当我单击下载链接时,它会在带有新 localhost url 的空白页面中打开文档?

本地主机仅用于测试目的。我最终会用我的域名替换它:

https://website-name.com/users/5/drivers_licence.jpg

稍后编辑我想通了,我在下面发布了解决方案作为答案

【问题讨论】:

  • 您能解释一下为什么要更改网址吗?为什么不能直接从存储中提供 blob?
  • 安全。该文件可能包含敏感信息,我不希望其他用户看到该图像(我不希望通过 blob URL 访问该信息)。另外,我不想暴露 blob 主机,这就是我想用自己的域替换它的原因。

标签: azure asp.net-web-api azure-storage azure-blob-storage


【解决方案1】:

如果您担心安全性并希望将容器的 ACL 保持为私有(顺便说一句,这是绝对正确的做法),您可以做的是在具有 Read 权限和简短的 blob 上创建一个 Shared Access Signature (SAS)到期。为了进一步保护 SAS,您可以在 SAS 上应用 IP ACL。使用 IP ACL,即使用户与其他用户共享 SAS URL,如果 IP 地址与 SAS 中配置的不同,其他用户将无法访问该 URL。

如果您担心不公开存储帐户终结点,可以将自定义域映射到您的 Blob 存储终结点,如 @forester123 所述。

如果您想通过您的网站域提供 Blob,唯一的解决方案是首先从您的 Web 服务器上的存储中下载 Blob,然后从那里提供 Blob。以您的示例为例,我假设容器名称为users,并且每个用户都有虚拟文件夹。在这种情况下,您需要做的是在您的网站中创建一个名为 users 的文件夹,然后在那里下载 blob 并将它们保存为本地文件。文件保存后,应该可以通过您的网站 URL 访问它们。

但是我不推荐这种方法,因为它效率不高。您需要首先将 blob 从存储下载到本地服务器并从那里提供服务。此外,每台服务器都会限制您可以保存多少本地数据,如果您不经常清理文件,则可能会耗尽磁盘空间。

我的建议是查看共享访问签名。你可以在这里阅读更多信息:https://azure.microsoft.com/en-in/documentation/articles/storage-dotnet-shared-access-signature-part-1/

【讨论】:

  • 感谢您的回复。我真正要查找的内容与我在另一个主题上找到的一段有关(也与您在此处的第 3 段有关),它被标记为 代理下载。请在此处查看接受的答案:stackoverflow.com/questions/7027656/… 到目前为止,我已经尝试将文件下载到我的 API 控制器中的 MemoryStream,然后我将对象作为 Task 返回。我可以只使用 javascript 在浏览器中返回文件,而不是保存文件,我希望它通过新的 url 在新选项卡中打开
  • 在新标签中打开图片意味着对您的网站的第二次请求,为此您需要将文件保存在服务器上的某个位置,以便浏览器可以找到该文件。
【解决方案2】:

您可以尝试为您的 Blob 存储端点配置自定义域名,查看详细信息here

【讨论】:

  • 感谢您的回复,我知道这一点,但这并不是我所需要的。我想我在这里寻找一个接受答案的例子(第三个标题 - 代理下载):stackoverflow.com/questions/7027656/…
  • @Toonsylvania 谢谢,我想我误解了你,因此答案不是你想要的,如果我得到任何解决方案,我会继续挖掘并更新我的答案。很抱歉给您带来不便。
  • 谢谢你,不用道歉,任何帮助都会非常受欢迎:)
【解决方案3】:

这就是我一直在寻找的,以防其他人正在寻找类似的解决方案:

public class BlobController : ApiController {

    private readonly BlobHelper helper = new BlobHelper();

    [Route("api/blob/{container}/{*filename}")]
    public HttpResponseMessage BlobDownload(string container, string filename) {
        var httpResponseMessage = new HttpResponseMessage();

        // 1) check if parameters are set

        // 2) try and get the blob
        var blob = helper.DownloadBlob(container, filename);

        // 3) check the response to see if blob actually exists

        // 4) return the file
        httpResponseMessage.StatusCode = HttpStatusCode.OK;
        httpResponseMessage.Content = new ByteArrayContent(blob.Stream);
        // don't forget to set the content type, this is important in order to mimic the described behaviour (IE: display an image in the browser)
        httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue(blob.ContentType); 

        return httpResponseMessage;
    }
}

【讨论】:

    猜你喜欢
    • 2019-04-06
    • 2021-06-20
    • 2019-02-12
    • 2012-04-23
    • 2021-12-12
    • 2019-05-31
    • 1970-01-01
    • 2018-08-03
    • 2018-11-21
    相关资源
    最近更新 更多