如何保护 azure blob 存储 url 不被任何使用开发人员工具的人检索

Posted

技术标签:

【中文标题】如何保护 azure blob 存储 url 不被任何使用开发人员工具的人检索【英文标题】:How to protect the azure blob storage urls from being retrieved by anyone using developer tools 【发布时间】:2018-11-03 14:23:19 【问题描述】:

我必须将图像/视频保存在 azure blob 中,然后在我的网站中使用它们。在做了一些研究之后,我发现你必须在 href 标记中包含 blob url,才能从 azure 中检索图像/视频。

但是,任何人都可以打开站点页面并获取该 blob 网址并滥用它。该站点还具有用户身份验证,因此只有在登录后用户才能在站点页面上看到该图像/视频。

还有其他方法可以从 azure 中检索 blob 吗?或者在开发人员工具中公开可见网址的任何其他解决方案?

我目前正在使用带有 Visual Studio 的 azure 模拟器。

【问题讨论】:

有几种方法可以解决这个问题。一种是不让 Blob 公开可用,而是通过后端服务(可能是 Azure 函数)检索它们。示例:api/images/uniquename。另一种方法是使用共享访问密钥,该密钥仅对所需图像具有只读访问权限。 @rickvdbosch 我不确定第一种解决方案是否可行。我将不使用 blob URL,而是使用 API URL,并且仍然能够访问 blob,除非我也保护 API 调用。第二种解决方案不能完全防止这种情况,但可以通过短期 SAS 令牌和适当的 IP ACL 在很大程度上控制它。 @GauravMantri 我知道第一个解决方案有效,因为我以前用过它:) 特别是使用 Azure Functions,您可以非常快速地创建这样的后端服务。我让函数使用 Azure SDK 从 blob 存储中检索文件并将它们返回以在前端使用。 @rickvdbosch 现在你让我很好奇 :)。我认为您的解释不适合 cmets。您介意提供详细的答案吗?这将非常有帮助。 @rickvdbosch 如果您能进一步详细说明将不胜感激:) 【参考方案1】:

不确定问题是否有效,但另一种非常简单的方法可能是

    将自定义域与您的存储端点一起使用 将您的 Blob 和容器设为私有 使用后端基础架构生成共享访问令牌,该令牌应仅在短时间内有效。 使用 SAS 生成 blob url。

如果您需要一起隐藏结构,所有步骤都可以与@rick 回答中提到的功能结合使用。

需要了解的一点是视频流需要到浏览器播放器,所以不可能有完美的方案。上面的选项也只会对访问进行时间限制。可能还有其他一些选项,例如服务器发送加密内容的消息层加密,并将在运行时解密您需要有一些自定义播放器功能,这可能会在服务器端产生更高的费用..

如果他有技能和高积极性,即使这也不会成为盗版视频的用户,但会以某种方式使其变得困难,这应该是这里的驱动点。

参考:https://docs.microsoft.com/en-us/azure/storage/common/storage-dotnet-shared-access-signature-part-1

【讨论】:

【参考方案2】:

我重新创建了一个 Azure 函数,它实现了我提到的第一个场景。存储帐户内的 Blob URL 未公开,并且容器及其中的所有内容都设置为私有。由于我不知道您的身份验证方案,所以我暂时跳过了它,但您可以通过多种方式保护它。

此代码中有一些快捷方式,但您会大致了解。代码如下:

public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "files/id")]
    HttpRequest req, string id, TraceWriter log)

    var account = CloudStorageAccount.Parse("UseDevelopmentStorage=true");
    var client = account.CreateCloudBlobClient();
    var container = client.GetContainerReference("sitecontent");
    var blob = container.GetBlockBlobReference(id);

    var stream = new MemoryStream();
    await blob.DownloadToStreamAsync(stream);
    stream.Seek(0, SeekOrigin.Begin);

    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
    result.Content = new StreamContent(stream);
    result.Content.Headers.ContentType =
            new MediaTypeHeaderValue("application/octet-stream");

    return result;

我已经通过从这样的 html 文件中引用它来测试它:

<img src="http://localhost:7071/api/files/techdays2017.jpg"  />

我使用的图像是 267KB,使用 Storage Emulator 进行本地测试时,Function 的响应时间均

【讨论】:

我不确定这将如何防止误用。我可以将此 URL 放入浏览器的地址栏中,然后我就可以访问该 blob。我在这里错过了什么吗? 嗯,存储中 blob 的完整 url 不再可见,blob 不再需要公开,并且可以保护函数,因此仅在用户登录时才下载文件在。 啊...我明白你的意思了。但是,是的,这需要保护函数,否则保持 blob 私有将无济于事。 当我看到你的回答时,我们在这里也做了同样的事情 :) 非常感谢 :) 这是非常错误的答案,最简单正确的答案是使用共享访问签名,绝对不需要通过azure函数重新路由网络调用。此外,这不支持带有进度等的部分下载,并且根本不适用于从 azure blob 传递视频。

以上是关于如何保护 azure blob 存储 url 不被任何使用开发人员工具的人检索的主要内容,如果未能解决你的问题,请参考以下文章

如何保护 azure blob

如何通过 URL 下载 Azure BLOB 存储文件

用于访问 Azure 存储中的私有 blob 的 URL

Azure Blob 存储:从 Excel 工作簿中删除密码

如何从 Azure 容器中的 blob 中获取所有 URL 的列表?

如何在 azure 中上传文件后获取 blob-URL