使用共享访问签名的 Azure Blob 存储虚拟目录
Azure Blob Storage Virtual Directories using Shared Access Signatures
我无法获得共享访问策略来处理 blob 存储中的虚拟目录。它适用于容器。据我所知,虚拟目录是容器,所以 SAS 应该可以工作吗?
当我尝试使用 SAS 访问虚拟目录中的资源时,我收到以下响应:
<?xml version="1.0" encoding="utf-8"?>
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:XXXXXXXX-000X-00XX-XXXX-XXXXXX000000 Time:2016-08-15T13:28:57.6925768Z</Message>
<AuthenticationErrorDetail>Signature did not match. String to sign used was r 2016-08-15T13:29:53Z /blob/xxxxxxxxxx/mycontainer 2015-12-11</AuthenticationErrorDetail>
</Error>
用于演示的示例代码:
public static async Task<string> GetFilePath()
{
var storageAccount = CloudStorageAccount.Parse( "DefaultEndpointsProtocol=https;AccountName=xxxxxxxxxx;AccountKey=xxxxxxxxxx" );
var blobClient = storageAccount.CreateCloudBlobClient();
var containerName = "mycontainer/myvd"; // remove /myvd and SAS will work fine
var containerReference = blobClient.GetContainerReference( containerName );
var blobName = "readme.txt";
var blobReference = await containerReference.GetBlobReferenceFromServerAsync( blobName );
var sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes( 1 );
sasConstraints.Permissions = SharedAccessBlobPermissions.Read;
var sasContainerToken = containerReference.GetSharedAccessSignature( sasConstraints );
var path = $"{blobClient.BaseUri.ToString()}{containerName}/{blobName}{sasContainerToken}";
return path;
}
出现此错误的原因是 Shared Access Signatures
仅在 blob 容器级别或 blob 级别受支持。事实上,在 Azure Blob 存储中没有 Virtual Directory
这样的东西;它仅支持 2 级层次结构:Blob 容器和 Blob。 Virtual Directory
只是您应用于文件 (blob) 名称的前缀。
基于此,我建议对您的代码进行以下更改:
var containerName = "mycontainer"; // remove /myvd and SAS will work fine
var containerReference = blobClient.GetContainerReference( containerName );
var blobName = "myvd/readme.txt"; //Your blob name is actually "myvd/readme.txt"
var blobReference = await containerReference.GetBlobReferenceFromServerAsync( blobName );
我无法获得共享访问策略来处理 blob 存储中的虚拟目录。它适用于容器。据我所知,虚拟目录是容器,所以 SAS 应该可以工作吗?
当我尝试使用 SAS 访问虚拟目录中的资源时,我收到以下响应:
<?xml version="1.0" encoding="utf-8"?>
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:XXXXXXXX-000X-00XX-XXXX-XXXXXX000000 Time:2016-08-15T13:28:57.6925768Z</Message>
<AuthenticationErrorDetail>Signature did not match. String to sign used was r 2016-08-15T13:29:53Z /blob/xxxxxxxxxx/mycontainer 2015-12-11</AuthenticationErrorDetail>
</Error>
用于演示的示例代码:
public static async Task<string> GetFilePath()
{
var storageAccount = CloudStorageAccount.Parse( "DefaultEndpointsProtocol=https;AccountName=xxxxxxxxxx;AccountKey=xxxxxxxxxx" );
var blobClient = storageAccount.CreateCloudBlobClient();
var containerName = "mycontainer/myvd"; // remove /myvd and SAS will work fine
var containerReference = blobClient.GetContainerReference( containerName );
var blobName = "readme.txt";
var blobReference = await containerReference.GetBlobReferenceFromServerAsync( blobName );
var sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes( 1 );
sasConstraints.Permissions = SharedAccessBlobPermissions.Read;
var sasContainerToken = containerReference.GetSharedAccessSignature( sasConstraints );
var path = $"{blobClient.BaseUri.ToString()}{containerName}/{blobName}{sasContainerToken}";
return path;
}
出现此错误的原因是 Shared Access Signatures
仅在 blob 容器级别或 blob 级别受支持。事实上,在 Azure Blob 存储中没有 Virtual Directory
这样的东西;它仅支持 2 级层次结构:Blob 容器和 Blob。 Virtual Directory
只是您应用于文件 (blob) 名称的前缀。
基于此,我建议对您的代码进行以下更改:
var containerName = "mycontainer"; // remove /myvd and SAS will work fine
var containerReference = blobClient.GetContainerReference( containerName );
var blobName = "myvd/readme.txt"; //Your blob name is actually "myvd/readme.txt"
var blobReference = await containerReference.GetBlobReferenceFromServerAsync( blobName );