1

我有一个 Blob 容器,其 ACL 设置为允许完全公共读取访问,因此任何人都可以读取和列出该容器中的 Blob。

我存储文件,以便我的客户使用的 WPF 客户端应用程序可以读取它们,但我不想让他们修改/删除/创建文件。

有谁知道在这种情况下应该使用什么连接字符串?

我希望指定没有帐户密钥和/或共享访问密钥的连接字符串,因为 blob 是公共的,但这不起作用 - StorageAccount.Parse 抛出 FormatException

4

3 回答 3

1

据我所知,StorageAccount 并不意味着连接到公共 blob。您只需使用WebClient之类的工具或任何其他可以通过公共 http/https 端点下载数据的工具,即可通过公共 URL 访问公共 blob。

于 2013-05-06T23:48:13.663 回答
1

正如前面的答案所提到的,最佳实践通常是使用共享访问签名 (SAS) 或存储的访问策略来控制对 blob 容器的访问。这些可用于创建访问令牌(字符串),您可以将其传递给您的客户,而无需透露您的帐户密钥。

但是,也可以指定对保存在容器中的 blob 和元数据的公共读取访问级别。公共访问权限是自动授予拥有容器或 blob 的公共访问 URL 的匿名用户的读取权限级别。您不能使用公共访问权限来授予匿名用户对容器的写入权限。如果您需要向不拥有 Azure 存储帐户的帐户密钥的用户授予写入权限,那么您将需要以 url 的形式为这些用户提供令牌,引用共享访问签名或共享访问策略。如果对 blob 容器的公共访问当前未关闭(私有),匿名用户将能够使用公共访问 url 读取容器中的所有 blob,如下所示。

http://grassy.blob.core.windows.net/container1/image2.jpg

创建容器时,可以将 publicAccess 属性的值设置为 BlobContainerPublicAccessType 枚举的适当常量。publicAccess 属性的值可以是以下三个常量之一,它们指定公共读取访问的级别。

• BLOB – 公众可以读取此容器内的 Blob 的内容和元数据,但不能读取容器元数据或列出容器内的 Blob。

• CONTAINER – 公众可以读取 blob 内容和元数据以及容器元数据,并且可以列出容器内的 blob。

• OFF – 指定不公开访问。只有帐户所有者才能读取此容器中的资源。

因此在这种情况下,公共访问级别可能设置为 CONTAINER。例如:

public static void main(String[] args) throws InvalidKeyException, URISyntaxException, StorageException 
   {            
   Account creds = new Account();               
   final String storageConnectionString = creds.getstorageconnectionstring();
   CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);
   CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
   CloudBlobContainer container = blobClient.getContainerReference("container1");
   container.createIfNotExist();
   BlobContainerPermissions containerPermissions = new BlobContainerPermissions();
   containerPermissions.setPublicAccess(BlobContainerPublicAccessType.CONTAINER);
   container.uploadPermissions(containerPermissions);
   BlobContainerPublicAccessType access1 = containerPermissions.getPublicAccess();
   System.out.println("Public access to " + container.getName() + " is set to: 
      " + access1);
  }

如果 container1 上的公共访问级别已设置为 CONTAINER,则匿名用户应该能够列出 container1 中的 blob,只知道存储帐户 AccountName(“grassy”)和容器名称,而无需知道 AccountKey。例如,匿名应用程序可能使用类似于以下的 java 代码:

public static void main(String[] args) throws InvalidKeyException, URISyntaxException, StorageException, FileNotFoundException, IOException 
   {            
   URI baseuri = new URI("http://grassy.blob.core.windows.net");
   CloudBlobClient blobclient = new CloudBlobClient(baseuri);
   CloudBlobContainer container = blobclient.getContainerReference("container1");   
      for (ListBlobItem blobItem : container.listBlobs()){System.out.println(blobItem.getUri());}   
   }

但是,正如所讨论的,最好避免授予匿名用户访问权限。而是使用 SAS 或策略控制对容器的访问,并将令牌仅传递给已知用户。

于 2013-05-07T16:47:05.560 回答
0

您可以为此目的使用共享访问签名。您可以做的是在 blob 容器上创建 SAS,该容器仅允许对 blob 容器的列出和读取权限,然后将该 SAS URI 分发给您的客户端。BlobContainer然后,您的代码可以使用该 SAS URI创建对象实例。

下面是使用 SAS URI 在 blob 容器中列出 blob 的示例代码:

static void ListBlobsWithStorageClientLibrary(string blobContainerSasUri)
{
    CloudBlobContainer blobContainer = new CloudBlobContainer(new Uri(blobContainerSasUri));
    var blobs = blobContainer.ListBlobs(null, true);
    foreach (var blob in blobs)
    {
        Console.WriteLine(blob.Uri);
    }
}

StorageCredentials其他替代方法是使用 SAS 令牌创建对象实例:http: //msdn.microsoft.com/en-us/library/windowsazure/jj682529.aspxCloudStorageAccount然后,您可以使用该 StorageCredentials 对象创建对象实例。

我写了一篇关于使用带有 blob 存储的共享访问签名的详细帖子,您可以在此处阅读:http: //gauravmantri.com/2013/02/13/revisiting-windows-azure-shared-access-signature/

于 2013-05-07T02:03:56.737 回答