繁体   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