MVC中的Azure blob存储安全选项

本文关键字:安全 选项 存储 blob 中的 Azure MVC | 更新日期: 2023-09-27 18:13:04

我正在研究一个解决方案,其中少数经过身份验证的用户应该具有对一组Azure Blob存储容器的完全访问权限。我目前已经实现了一个系统与公共访问,并想知道我是否需要使系统进一步复杂化,或者如果这个系统将是足够安全的。我已经简要地研究了共享访问签名(SAS)是如何工作的,但我不确定这是否真的有必要,因此请您提供一些见解。目标是只允许经过身份验证的用户完全访问blob容器及其内容。

当前系统以以下方式设置权限(c#, MVC):

// Retrieve a reference to my image container 
myContainer = blobClient.GetContainerReference("myimagescontainer");
// Create the container if it doesn't already exist
if (myContainer.CreateIfNotExists())
{
    // Configure container for public access
    var permissions = myContainer.GetPermissions();
    permissions.PublicAccess = BlobContainerPublicAccessType.Container;
    myContainer.SetPermissions(permissions);
}
因此,只要您有完整的URL,就可以完全访问所有blob,但是似乎不可能直接通过URL列出容器中的blob:
// This URL allows you to view one single image directly:
'https://mystorageaccount.blob.core.windows.net/mycontainer/mycontainer/image_ea644f08-3263-4a7f-9be7-bc42efbf8939.jpg'
// These URLs appear to return to nothing but an error page:
'https://mystorageaccount.blob.core.windows.net/mycontainer/mycontainer/'
'https://mystorageaccount.blob.core.windows.net/mycontainer/'
'https://mystorageaccount.blob.core.windows.net/'

我不认为这是一个问题,认证的用户共享完整的url,允许公众访问单个图像;但是,只有经过身份验证的用户才能列出、浏览或直接访问容器以检索其他映像。

我的问题变成了我是否应该进一步保护系统,例如使用SAS,当它现在看起来像预期的那样工作时,或者让系统保持原样。您可能会理解,如果不是严格需要的话,我不想使系统复杂化。谢谢!

我最终使用的解决方案如下:)

MVC中的Azure blob存储安全选项

我使用Ognyan Dimitrov的"Approach 2"在浏览器窗口内提供存储在私有blob容器("No public read access")中的小型pdf:

public ActionResult ShowPdf()
{
    string fileName = "fileName.pdf";
    var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
    var blobClient = storageAccount.CreateCloudBlobClient();
    var container = blobClient.GetContainerReference("containerName");
    var blockBlob = container.GetBlockBlobReference(fileName);
    Response.AppendHeader("Content-Disposition", "inline; filename=" + fileName);
    return File(blockBlob.DownloadByteArray(), "application/pdf");
}

配置文件

<configuration>
    <appSettings>
        <add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=account-name;AccountKey=account-key" />
    </appSettings>
</configuration>

…这对我来说是完美的!

所以,这就是我最后做的。感谢Neil和Ognyan带我去那里。

它的工作方式如下:

  • 所有图像都是私有的,如果没有有效的SAS
  • ,根本无法查看
  • blob的添加、删除和修改都是在控制器内部进行的,都是私有的。这些任务不需要SAS或其他过程。
  • 当一个图像要显示给用户时(无论是匿名的还是经过身份验证的),一个函数生成一个快速过期的SAS,它只允许浏览器在页面生成和刷新时下载图像(或blob),但不能复制/粘贴一个有用的URL到外部。
我首先显式地将容器权限设置为Private(根据Ognyan,这也是默认设置):
// Connect to storage account
...
// Retrieve reference to a container. 
myContainer= blobClient.GetContainerReference("mycontainer");
// Create the container if it doesn't already exist.
if (myContainer.CreateIfNotExists())
{
    // Explicitly configure container for private access
    var permissions = myContainer.GetPermissions();
    permissions.PublicAccess = BlobContainerPublicAccessType.Off;
    myContainer.SetPermissions(permissions);   
}

然后,当想要显示图像时,我在blob的原始存储路径中添加了一个SAS字符串:

public string GetBlobPathWithSas(string myBlobName)
{
    // Get container reference
    ...
    // Get the blob, in my case an image
    CloudBlockBlob blob = myContainer.GetBlockBlobReference(myBlobName);        
    // Generate a Shared Access Signature that expires after 1 minute, with Read and List access 
    // (A shorter expiry might be feasible for small files, while larger files might need a 
    // longer access period)
    string sas = myContainer.GetSharedAccessSignature(new SharedAccessBlobPolicy()
    {
        SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(1),
        Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.List
    });
    return (blob.Uri.ToString() + sas).ToString();
}
然后从razor视图中调用GetBlobPathWithSas()-函数,这样每次页面刷新都会给出一个有效的路径+sas来显示图像:
<img src="@GetPathWithSas("myImage")" />

总的来说,我觉得这个参考资料很有用:

http://msdn.microsoft.com/en-us/library/ee758387.aspx

希望这对某人有所帮助!

如果您只想要您的授权。用户要访问容器,必须将容器设为私有。否则,这些内容就会被公开,其他人看到这些"几乎私密"的内容只是时间问题,而作为开发者的你会感到尴尬。

方法1:你发送一个链接给你的授权用户。在本例中,您向用户提供一个SAS链接,用户直接从blob下载内容。您必须生成具有短访问窗口的SAS签名,以便您的用户可以获得您的内容并下载/打开它,并且在他们离开网站后,链接将过期,内容将不再可用。这是为了防止他们不小心通过电线发送链接,其他人稍后获得私有内容。

方法2:您的web服务器获取内容并将其传递给您的客户端在这种情况下,只有您的web应用程序将具有访问权限,而不需要生成SAS签名。返回FileContentResult(在MVC的情况下),就可以了。缺点是,你的网络服务器必须下载文件之前给客户端-双重流量。在这里,你必须小心地处理Blob->Web下载,因为如果3个用户尝试一起下载一个200mb的文件,并且你将它存储在RAM中,它将耗尽。

** UPDATE **

@Intexx提供了您需要的文档的更新链接。

如果您使用的是公共容器,那么您实际上并没有限制对经过身份验证的用户的访问。

如果规范说"只有经过认证的用户才能访问",那么我个人认为使用公共容器是不可接受的。SAS并不难——库完成了大部分工作。

顺便说一句:列出一个容器中的项目的格式是:https://myaccount.blob.core.windows.net/mycontainer?restype=container&comp=list