我有一个 Blob 容器,其 ACL 设置为允许完全公共读取访问,因此任何人都可以读取和列出该容器中的 Blob。
我存储文件,以便我的客户使用的 WPF 客户端应用程序可以读取它们,但我不想让他们修改/删除/创建文件。
有谁知道在这种情况下应该使用什么连接字符串?
我希望指定没有帐户密钥和/或共享访问密钥的连接字符串,因为 blob 是公共的,但这不起作用 - StorageAccount.Parse 抛出 FormatException
据我所知,StorageAccount 并不意味着连接到公共 blob。您只需使用WebClient之类的工具或任何其他可以通过公共 http/https 端点下载数据的工具,即可通过公共 URL 访问公共 blob。
正如前面的答案所提到的,最佳实践通常是使用共享访问签名 (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 或策略控制对容器的访问,并将令牌仅传递给已知用户。
您可以为此目的使用共享访问签名。您可以做的是在 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.aspx。CloudStorageAccount
然后,您可以使用该 StorageCredentials 对象创建对象实例。
我写了一篇关于使用带有 blob 存储的共享访问签名的详细帖子,您可以在此处阅读:http: //gauravmantri.com/2013/02/13/revisiting-windows-azure-shared-access-signature/