然后我将其应用到我的场景中。
我编写了一个工具,用于将合作伙伴的数据上传到Azure Blob存储中,然后它将被一些内部团队使用: YYYY-MM(容器) (DD-GUID)(前缀) File1.zip File2.zip ……
我为每个容器创建了两个策略: 1. 只允许合作伙伴写入Blob,不允许其他操作。 2. 允许我们的内部团队列出和读取(下载)容器中的所有Blob。
我的想法是只需将正确的策略交给相应的接收者即可;然而,我的实现效果不如预期。
我使用以下方法为每个容器创建了两个策略,当然每个策略都有正确的权限:
static void CreateSharedAccessPolicy(CloudBlobClient blobClient, CloudBlobContainer container, string policyName)
{
//Create a new stored access policy and define its constraints.
SharedAccessBlobPolicy sharedPolicy = new SharedAccessBlobPolicy()
{
SharedAccessExpiryTime = DateTime.UtcNow.AddHours(10),
Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.List
};
//Get the container's existing permissions.
BlobContainerPermissions permissions = new BlobContainerPermissions();
//Add the new policy to the container's permissions.
permissions.SharedAccessPolicies.Clear();
permissions.SharedAccessPolicies.Add(policyName, sharedPolicy);
container.SetPermissions(permissions);
}
我首先创建了只写策略,然后再创建了读取和列出策略。我发现第一个策略似乎不起作用,所有内容都返回403 Forbidden,而对于第二个策略,只有列出blob文件能够正常工作,但是读取(我尝试下载blob文件但是得到了404 Not Found)无法正常工作。
看起来我在这里忽略了一些非常基本的东西。请您帮忙看看我的方法有什么问题。
我用来测试容器权限的代码,我还注意到Azure文档中提到的容器上的读取权限实际上并不能正常工作。在这里,我试图找到一种简单的方式,只需提供存储访问策略即可允许用户列出并下载容器中的所有blob文件,而不是为每个blob文件提供签名。:
static void UseContainerSAS(string sas) { // 使用提供的SAS尝试执行容器操作。
//Return a reference to the container using the SAS URI.
CloudBlobContainer container = new CloudBlobContainer(new Uri(sas));
//Create a list to store blob URIs returned by a listing operation on the container.
List<Uri> blobUris = new List<Uri>();
try
{
//Write operation: write a new blob to the container.
CloudBlockBlob blob = container.GetBlockBlobReference("blobCreatedViaSAS.txt");
string blobContent = "This blob was created with a shared access signature granting write permissions to the container. ";
MemoryStream msWrite = new MemoryStream(Encoding.UTF8.GetBytes(blobContent));
msWrite.Position = 0;
using (msWrite)
{
blob.UploadFromStream(msWrite);
}
Console.WriteLine("Write operation succeeded for SAS " + sas);
Console.WriteLine();
}
catch (StorageException e)
{
Console.WriteLine("Write operation failed for SAS " + sas);
Console.WriteLine("Additional error information: " + e.Message);
Console.WriteLine();
}
try
{
//List operation: List the blobs in the container, including the one just added.
foreach (ICloudBlob blobListing in container.ListBlobs())
{
blobUris.Add(blobListing.Uri);
}
Console.WriteLine("List operation succeeded for SAS " + sas);
Console.WriteLine();
}
catch (StorageException e)
{
Console.WriteLine("List operation failed for SAS " + sas);
Console.WriteLine("Additional error information: " + e.Message);
Console.WriteLine();
}
try
{
CloudBlockBlob blob = container.GetBlockBlobReference(blobUris[0].ToString());
MemoryStream msRead = new MemoryStream();
msRead.Position = 0;
using (msRead)
{
blob.DownloadToStream(msRead);
Console.WriteLine(msRead.Length);
}
Console.WriteLine("Read operation succeeded for SAS " + sas);
Console.WriteLine();
}
catch (StorageException e)
{
Console.WriteLine("Read operation failed for SAS " + sas);
Console.WriteLine("Additional error information: " + e.Message);
Console.WriteLine();
}
Console.WriteLine();
try
{
//Delete operation: Delete a blob in the container.
CloudBlockBlob blob = container.GetBlockBlobReference(blobUris[0].ToString());
blob.Delete();
Console.WriteLine("Delete operation succeeded for SAS " + sas);
Console.WriteLine();
}
catch (StorageException e)
{
Console.WriteLine("Delete operation failed for SAS " + sas);
Console.WriteLine("Additional error information: " + e.Message);
Console.WriteLine();
}
}
DateTime.UtcNow.AddMinutes(-5)
。 - Brendan Green