简体   繁体   English

MVC 中的 Azure blob 存储安全选项

[英]Azure blob storage security options in MVC

I am working on a solution where a small number of authenticated users should have full access to a set of Azure Blob Storage containers.我正在研究一种解决方案,其中少数经过身份验证的用户应该可以完全访问一组 Azure Blob 存储容器。 I have currently implemented a system with public access, and wonder if I need to complicate the system further, or if this system would be sufficiently secure.我目前已经实现了一个公共访问系统,并想知道我是否需要进一步复杂化系统,或者这个系统是否足够安全。 I have looked briefly into how Shared Access Signatures (SAS) works, but I am not sure if this really is necessary, and therefore ask for your insight.我已经简要地研究了共享访问签名 (SAS) 的工作原理,但我不确定这是否真的有必要,因此请您提供见解。 The goal is to allow only authenticated users to have full access to the blob containers and their content.目标是只允许经过身份验证的用户对 blob 容器及其内容具有完全访问权限。

The current system sets permissions in the following manner (C#, MVC):当前系统通过以下方式设置权限(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);
}

As a result, all blobs are fully accessible as long as you have the complete URL, but it does not seem to be possible to list the blobs in the container directly through the URL:因此,只要您拥有完整的 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/'

I do not find it an issue that authenticated users share complete URLs, allowing public access to a single image;我不认为经过身份验证的用户共享完整的 URL,允许公共访问单个图像的问题; however, no one but the authenticated users should be able to list, browse or access the containers directly to retrieve other images.然而,除了经过身份验证的用户之外,没有人能够直接列出、浏览或访问容器以检索其他图像。

My question then becomes whether I should secure the system further, for instance using SAS, when it right now appears to work as intended, or leave the system as-is.然后我的问题变成了我是否应该进一步保护系统,例如使用 SAS,当它现在看起来按预期工作时,还是让系统保持原样。 You might understand that I would like to not complicate the system if not strictly needed.您可能会理解,如果不是严格需要,我不想使系统复杂化。 Thanks!谢谢!

The solution I ended up using has been given below :)下面给出了我最终使用的解决方案:)

I use Ognyan Dimitrov's "Approach 2" to serve small PDFs stored in a private blob container ("No public read access") inside a browser window like this:我使用 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");
}

with config file带配置文件

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

...which works perfect for me! ...这对我来说非常适合!

If you want only your auth.如果你只想要你的 auth. users to have access you have to make the container private.拥有访问权限的用户必须将容器设为私有。 Otherwise it will be public and it is only a matter of time that somebody else gets to the "almost private" content and you as a developer get embarrassed.否则它将是公开的,其他人获得“几乎私密”的内容只是时间问题,而您作为开发人员会感到尴尬。

Approach 1 : You send a link to your authorized user.方法 1:您向授权用户发送链接。 In this case you give a SAS link to the user and he downloads his content from the blob directly.在这种情况下,您向用户提供 SAS 链接,他会直接从 blob 下载他的内容。 You have to generate SAS signatures with short access window so that your users can get your content and download it/ open it and after they are gone from the site the link will expire and the content will be no longer available.您必须生成具有短访问窗口的 SAS 签名,以便您的用户可以获取您的内容并下载/打开它,并且在他们离开站点后,链接将过期并且内容将不再可用。 This is in case that they accidentally send the link over the wire and somebody else gets to the private content later.这是为了防止他们不小心通过网络发送链接,而其他人稍后会访问私人内容。

Approach 2 : Your web server gets the content and delivers it to your clients In this case only your web app will have the access and no SAS signatures have to be generated.方法 2:您的 Web 服务器获取内容并将其交付给您的客户端在这种情况下,只有您的 Web 应用程序可以访问并且无需生成 SAS 签名。 You return FileContentResult ( in case of MVC ) and you are ready.您返回 FileContentResult (在 MVC 的情况下)并且您准备好了。 The downside is that your web server have to download the file prior to giving it to the client - double traffic.缺点是您的 Web 服务器必须在将文件提供给客户端之前下载文件 - 双重流量。 Here you have to handle the Blob->Web download carefully because if 3 users try to download a 200 MB file in together and you are storing it in your RAM - it will be depleted.在这里,您必须小心处理 Blob->Web 下载,因为如果 3 个用户尝试一起下载 200 MB 的文件,而您将其存储在您的 RAM 中 - 它将会耗尽。

** UPDATE ** ** 更新 **

@Intexx provided an updated link to the docs you need. @Intexx 提供了您需要的文档的更新链接。

So, here is what I ended up doing.所以,这就是我最终要做的。 Thanks to Neil and Ognyan for getting me there.感谢 Neil 和 Ognyan 让我到达那里。

It works as following:它的工作原理如下:

  • All images are private, and cannot be viewed at all without having a valid SAS所有图像都是私有的,不能完全不需要一个有效的SAS查看
  • Adding, deletion and modification of blobs are made within the controller itself, all privately. blob 的添加、删除和修改都是在控制器内部进行的,所有这些都是私下进行的。 No SAS or additional procedures are needed for these tasks.这些任务不需要 SAS 或其他过程。
  • When an image is to be displayed to the user (either anonymously or authenticated), a function generates an SAS with a fast expiry is that merely allows the browser to download the image (or blob), upon page generation and refresh, but not copy/paste a useful URL to the outside.当要向用户显示图像(匿名或经过身份验证)时,一个函数会生成一个快速到期的 SAS,它只允许浏览器在页面生成和刷新时下载图像(或 blob),而不是复制/ 将有用的 URL 粘贴到外部。

I first explicitly set the container permissions to Private (this is also the default setting, according to Ognyan):我首先将容器权限显式设置为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);   
}

Then later, when wanting to display the image, I added an SAS string to the original storage path of the blob:然后后来想显示图片的时候,我在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();
}

I then called the GetBlobPathWithSas() -function from within the razor view, so that each page refresh would give a valid path+sas for displaying the image:然后我从 razor 视图中调用了GetBlobPathWithSas()函数,这样每次页面刷新都会给出一个有效的路径+sas来显示图像:

<img src="@GetPathWithSas("myImage")" />

In general, I found this reference useful:总的来说,我发现这个参考很有用:

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

Hope that helps someone!希望对某人有所帮助!

If you are using a public container then you are not really restricting access to authenticated users.如果您使用的是公共容器,那么您并没有真正限制对经过身份验证的用户的访问。

If the spec said "only authenticated users should have access" then I personally would find using a public container to be unacceptable.如果规范说“只有经过身份验证的用户才能访问”,那么我个人会发现使用公共容器是不可接受的。 SAS is not very hard - the libraries do most of the work. SAS 不是很难——图书馆完成了大部分工作。

BTW: the format to list the items in a container is: https://myaccount.blob.core.windows.net/mycontainer?restype=container&comp=list顺便说一句:列出容器中项目的格式是: 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