簡體   English   中英

MVC 中的 Azure blob 存儲安全選項

[英]Azure blob storage security options in MVC

我正在研究一種解決方案,其中少數經過身份驗證的用戶應該可以完全訪問一組 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,當它現在看起來按預期工作時,還是讓系統保持原樣。 您可能會理解,如果不是嚴格需要,我不想使系統復雜化。 謝謝!

下面給出了我最終使用的解決方案:)

我使用 Ognyan Dimitrov 的“方法 2”在瀏覽器窗口內提供存儲在私有 blob 容器(“無公共讀取訪問”)中的小型 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>

...這對我來說非常適合!

如果你只想要你的 auth. 擁有訪問權限的用戶必須將容器設為私有。 否則它將是公開的,其他人獲得“幾乎私密”的內容只是時間問題,而您作為開發人員會感到尷尬。

方法 1:您向授權用戶發送鏈接。 在這種情況下,您向用戶提供 SAS 鏈接,他會直接從 blob 下載他的內容。 您必須生成具有短訪問窗口的 SAS 簽名,以便您的用戶可以獲取您的內容並下載/打開它,並且在他們離開站點后,鏈接將過期並且內容將不再可用。 這是為了防止他們不小心通過網絡發送鏈接,而其他人稍后會訪問私人內容。

方法 2:您的 Web 服務器獲取內容並將其交付給您的客戶端在這種情況下,只有您的 Web 應用程序可以訪問並且無需生成 SAS 簽名。 您返回 FileContentResult (在 MVC 的情況下)並且您准備好了。 缺點是您的 Web 服務器必須在將文件提供給客戶端之前下載文件 - 雙重流量。 在這里,您必須小心處理 Blob->Web 下載,因為如果 3 個用戶嘗試一起下載 200 MB 的文件,而您將其存儲在您的 RAM 中 - 它將會耗盡。

** 更新 **

@Intexx 提供了您需要的文檔的更新鏈接。

所以,這就是我最終要做的。 感謝 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

希望對某人有所幫助!

如果您使用的是公共容器,那么您並沒有真正限制對經過身份驗證的用戶的訪問。

如果規范說“只有經過身份驗證的用戶才能訪問”,那么我個人會發現使用公共容器是不可接受的。 SAS 不是很難——圖書館完成了大部分工作。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM