没有帐户密钥的Azure存储连接字符串 - 公共容器

时间:2013-05-06 22:07:07

标签: azure storage blob acl

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

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

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

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

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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。

•容器 - 公众可以读取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或策略控制对容器的访问,并将令牌传递给仅已知用户。

答案 2 :(得分:0)

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

以下是使用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);
    }
}

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

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