1
votes

I can't get shared access policies to work with virtual directories in blob storage. It works fine for containers. As far as I know, virtual directories are containers so SAS should work?

When I attempt to access a resource in a virtual directory using a SAS I get this response:

<?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>

Example code to demonstrate:

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;
}
1

1 Answers

1
votes

Reason for this error is because Shared Access Signatures are only supported either at blob container level or blob level. In fact, in Azure Blob Storage there's no such thing as a Virtual Directory; it only supports 2-level hierarchy: Blob Container & Blob. A Virtual Directory is simply a prefix that you apply to a file (blob) name.

Based on this, I would recommend making following changes to your code:

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 );