我有一个代码,该代码以交互方式验证用户身份,然后使用Azure存储数据移动库(here's the documentation)从Azure Blob存储下载blob。为了下载Blob,我生成了SAS令牌,该令牌已使用为身份验证的用户获取的用户委托密钥进行了签名。
我有2个用户用于测试。
其中之一具有“贡献者”角色和“存储Blob数据贡献者”角色。对于该用户,一切正常。
第二个用户具有“存储Blob委托人”角色(获取委托密钥是必需的)。此用户还对blob容器中的文件夹之一及其所有内容具有读取,写入和执行权限,并且对blob容器本身具有执行权限(以便能够遍历他拥有的文件夹)。
因此,在以交互方式对第二个用户进行身份验证并获得TokenCredential之后,我可以列出文件夹内容,重命名文件和文件夹,创建新文件夹(我将Azure.Storage.Files.DataLake nuget用于这些操作)。当我尝试使用数据移动库上载或下载任何文件时,出现StorageException:
此请求无权使用此权限执行此操作。
重申一下,对于第一个用户,一切正常。因此在我看来,SAS令牌会忽略使用ACL分配的权限。
我的代码如下
public static void Download(string containerName, string sourcePathInsideContainer,
string destinationLocalPath)
{
string storageAccountPath = "https://myaccountname.blob.core.windows.net/";
string storageAccountName = "myaccountname";
var sasToken = GetSasToken(storageAccountPath, containerName, storageAccountName);
CloudStorageAccount account = new CloudStorageAccount(
new StorageCredentials(sasToken), storageAccountName, "core.windows.net", true);
CloudBlobClient blobClient = account.CreateCloudBlobClient();
CloudBlobContainer blobContainer = blobClient.GetContainerReference(containerName);
CloudBlob sourceBlob = blobContainer.GetBlockBlobReference(sourcePathInsideContainer);
// Download blob
TransferManager.DownloadAsync(sourceBlob, destinationLocalPath).Wait();
}
private static string GetSasToken(string storageAccountPath, string containerName, string storageAccountName)
{
TokenCredential token = // acquire token interactively ...
BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(storageAccountPath), token);
var validFrom = DateTimeOffset.UtcNow;
var validTo = DateTimeOffset.UtcNow.AddDays(1);
var delegationKey = blobServiceClient.GetUserDelegationKey(validFrom, validTo);
// Create a SAS token that's valid for one day.
var sasBuilder = new BlobSasBuilder()
{
BlobContainerName = containerName,
Resource = "c",
StartsOn = validFrom,
ExpiresOn = validTo
};
// Specify read permissions for the SAS.
sasBuilder.SetPermissions(BlobSasPermissions.All);
// Use the key to get the SAS token.
return sasBuilder.ToSasQueryParameters(delegationKey, accountName).ToString();
}