2013-05-06 74 views
1

我有一个blob容器,该ACL设置为允许完全公共读取访问,以便任何人都可以读取和列出该容器中的blob。Azure存储连接字符串没有帐户密钥 - 公共容器

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

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

我希望没有指定帐户键连接字符串和/或共享访问密钥由于斑点被公开,但没有奏效 - StorageAccount.Parse抛出出现FormatException

回答

0

正如前面的答案中提到,最好的做法通常是控制访问您的blob容器使用共享访问签名(SAS)或存储的访问策略。这些可用于创建访问令牌(字符串),您可以传递给客户端而不会泄露您的账户密钥。

但是,还可以指定对容器中保存的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公众访问级别已设置的容器,匿名用户应该能够列出container1只知道存储帐户帐户名(“草”)的斑点和容器名称,但不需要知道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或策略控制对容器的访问,并将令牌传递给已知用户。

+0

MArk,这正是我的使用案例 - 我有一个CONTAINER访问策略的容器,允许所有用户列出并下载数据 - 完全同意你写的内容。 我的问题涉及到,我的所有客户端都有WPF应用程序,这些应用程序必须在应用程序第一次启动时在该容器中列出*文件*,并将所有脚本等列表找出并执行一些活动它。问题是,从这一刻起,我不知道如何将app.config文件作为容器连接字符串放入,因为AFAIK即使对于PUBLIC CONTAINERS - 键所需 – 2013-05-11 12:00:36

+0

请参阅我的答案的更新。添加的代码片段应该允许任何匿名用户在容器中列出blob。 – 2013-05-13 17:33:30

+0

好吧,您的基于代码的解决方案使我尝试将配置文件中的连接字符串设置为简单 那(显然)工作 - 谢谢。 – 2013-05-15 07:11:43

1

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

+1

我想让我的WPF客户端应用程序直接访问BLOB的原因是为了避免所有流量通过我的Web服务器,并使用Azure本身扩展文件传输而不会导致我的网站出现性能问题。 – 2013-05-11 11:50:39

0

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

下面是使用SAS URI斑点容器列出斑点的代码示例:

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/

+0

我知道SAS,但它是PUBLIC容器 - 如果我给你简单的URL,并且你在浏览器中输入它,你会得到这个文件 - 完全没有问题。这里的第二件事是,如果我的网站关闭了,那么就没有办法给他们发送令牌。我的设计目标是向他们提供始终以最小的失败风险工作的云存储文档 - 我最好只依赖Azure blob存储可用性。 – 2013-05-11 11:54:27