英文:
Allow access to blobs in azure storage to display in a browser from an app service
问题
我有一个Blob存储帐户,不允许公共访问。因此,图像容器是私有的,包含图像。
一个应用服务运行并托管一个Razor Pages Web应用程序。Web应用程序具有系统托管的身份,并使用DefaultAzureCredentials
来避免在appsettings中使用密钥,并且具有作为Blob Contributor角色访问存储帐户的权限。
在这种配置下,通过Azure B2C进行身份验证的用户可以按预期上传文件到存储、列出它们、删除、读取和设置元数据等等。然而,当我从BlobClient
中检索一个Blob(图像)的URI并在cshtml文件中显示它时,我收到了一个409状态码。
换句话说,在服务器上执行的所有操作都正常工作,但存储帐户拒绝在应用程序的浏览器Get请求中显示图像。这对于localhost和在urlxyz.azurewebsites.net
上的生产环境都是正确的。
我相信应用服务有权访问数据,因此可以检索给定图像的URL,但随后是浏览器发出请求,从而被存储帐户拒绝。
我想知道如何在不使用SAS令牌的情况下解决这个问题(它们的确有效)。换句话说,我想知道是否有可能:
-
当在浏览器的URL栏中粘贴或从简单的curl中获取时,禁止从URL
https://xyz.blob.core.windows.net/images/image1.jpg
获取。 -
当从网站发出Get请求时允许将图像发送到浏览器(考虑Referer头,例如)。
是否可能以及如何实现?
编辑:我找到了相关问题,但它们已过时且没有结论,除了指向SAS令牌。限制SAS的问题在于URL可以被任何人读取,而不仅仅是已登录的用户。欢迎提供解决方案,希望自从这些SO问题发布以来已经取得了一些进展在这里和在这里。
英文:
I have a blob storage account disallowing public access. An image container is thus private and contains images.
An app service runs and hosts a Razor Pages web app. The web app has a system managed identity and uses the DefaultAzureCredentials
to avoid keys in appsettings, and has access to the storage account as a Blob Contributor role.
With this configuration, users authenticated with azure b2c are able to upload files to the storage, list them, delete, read and set metada and so on, as expected. However, when I retrieve a blob (image) Uri from the BlobClient
and display it in a cshtml file, I receive a 409 status code.
Said differently, all operations made on the server are working properly, but the storage account denies displaying the image in a Get request from browser of that app. This is true for localhost and in production on the url xyz.azurewebsites.net
.
I believe that the app service has the right to access the data and thus can retrieve the url of a given image, but it is then the browser that makes the request and thus gets rejected from the storage account.
I would like to know how I can resolve this problem without ressorting to SAS tokens (they work indeed). Said differently, I wonder if there is a possibility to:
-
Disallow gets from the url
https://xyz.blob.core.windows.net/images/image1.jpg
when pasted in the browser url bar, or from a simple curl. -
Allow sending the image to the browser when the get is made from the website (considering the Referer header for instance?).
Is that possible and how?
Edit: I have found related issues but they are outdated and not conslusive besides pointing to SAS tokens. What is limiting SAS is that the url can be read by anyone who gets it and not only the logged in user. A solution is most welcomed, in the hope that some progress has been made since these SO questions have been posted here and here.
答案1
得分: 1
在你的代码中,BlobClient 中使用的 DefaultAzureCredentials 为你获取了访问令牌,并将该令牌附加到了请求的授权标头中,因此请求成功访问了存储在你的 Blob 存储中的图像。
然而,当你使用浏览器时,它不会自动添加授权标头。
没有授权信息,你将无权访问受保护的内容。
你可以为 Blob 存储生成 SAS,并将 SAS 附加到你的 URL 中以访问内容。
一个权宜之计(并非完美解决方案)是你可以设置 SAS 令牌的生存期,客户端需要定期更新 SAS 令牌。
(我在 Microsoft 的 Azure SDK 团队工作)
英文:
In your code, DefaultAzureCredentials which was used in your BlobClient got the access token for you and attached the token in the auth header in your request. Hence the request successfully accessed the images in your blob storage.
Well, when you used browser, it did not add the auth header automatically.
W/o the auth information, you did not have permission to access to protected content.
You can generate SAS for the blob storage and attached the SAS in your url to access the content.
One workaround (it is not a perfect solution) is that you can set the lifetime of the SAS token and the clients need to update the SAS token periodically.
(I work in Azure SDK team in Microsoft)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论