Question

I'm having trouble with Azure Blobs and Shared Access Signatures when they expire. I need to grant access to a blob for longer than 1 hour (7 days), so I'm using a named container policy, but unfortunately I can't seem to generate new urls once those 7 days are up.

I have the following code to create the "default" policy. Note in this code, I'm setting the expiration to be 1 minute from now, to make it easier to test:

CloudStorageAccount account = new CloudStorageAccount(credentials, true);

CloudBlobClient client = new CloudBlobClient(account.BlobEndpoint, credentials);

CloudBlobContainer container = client.GetContainerReference("files");

SharedAccessPolicy sharedAccessPolicy = new SharedAccessPolicy();
sharedAccessPolicy.Permissions = SharedAccessPermissions.Read;
sharedAccessPolicy.SharedAccessStartTime = DateTime.UtcNow;
sharedAccessPolicy.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(1);

BlobContainerPermissions blobContainerPermissions = new BlobContainerPermissions();
blobContainerPermissions.SharedAccessPolicies.Add("default", sharedAccessPolicy);

container.SetPermissions(blobContainerPermissions);

I then create a SharedAccessSignature url with the following:

CloudStorageAccount account = new CloudStorageAccount(credentials, true);

CloudBlobClient client = new CloudBlobClient(account.BlobEndpoint, credentials);

CloudBlobContainer container = client.GetContainerReference("files");

CloudBlob blob = container.GetBlobReference(path);

string sas = blob.GetSharedAccessSignature(new SharedAccessPolicy(), "default");

Console.WriteLine(blob.Uri.AbsoluteUri + sas);

This generates a url, and the url works properly for the next minute (or 7 days in the real code). Once the one minute is over, the url is invalid and no longer works, as expected.

But once that expiration is past, I run the code again to generate a new url. Unfortunately, it generates the same url, which is still invalid.

Are the start/end times for container policies absolute, meaning when I set that policy right now:

sharedAccessPolicy.SharedAccessStartTime = DateTime.UtcNow;
sharedAccessPolicy.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(1);

anything using that policy is only valid from 10:10am (EDT) to 10:11am (EDT) today?

Was it helpful?

Solution

One thing you could do is create your access policy without expiry date. You specify the expiry date when you're creating the signed URL.

So your code would look something like:

        SharedAccessPolicy sharedAccessPolicy = new SharedAccessPolicy();
        sharedAccessPolicy.Permissions = SharedAccessPermissions.Read;
        sharedAccessPolicy.SharedAccessStartTime = DateTime.UtcNow;
        //sharedAccessPolicy.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(1); No need to define expiry time here.

        BlobContainerPermissions blobContainerPermissions = new BlobContainerPermissions();
        blobContainerPermissions.SharedAccessPolicies.Add("default", sharedAccessPolicy);

        container.SetPermissions(blobContainerPermissions);

        Console.WriteLine("Press any key to continue....");
        Console.ReadLine();
        CloudBlob blob = container.GetBlobReference(path);

        string sas = blob.GetSharedAccessSignature(new SharedAccessPolicy()
        {
            SharedAccessExpiryTime = DateTime.UtcNow.AddDays(7),//add expiry date only when you're creating the signed URL
        }
            , "default");

        Console.WriteLine(blob.Uri.AbsoluteUri + sas);

        Process.Start(new ProcessStartInfo(blob.Uri.AbsoluteUri + sas));

        Console.WriteLine("Press any key to continue....");
        Console.ReadLine();

Will this work for you? Obviously you would need to regenerate the URL after 7 days but you don't have to make any changes to your access policy.

Hope this helps.

OTHER TIPS

With a 1 minute expiration you might be hitting clock skew effects between the SAS generation box and Windows Azure Storage. You should use a longer interval. I did a post going into the gory depths of shared access signatures, that you might find helpful.

You may be hitting the maximum on container level access policies.

A stored access policy includes a name up to 64 characters long that is unique within the container. This name appears in the signedidentifier field on Shared Access Signatures that link to a stored access policy. A container can include up to 5 stored access policies. Each policy can be used by any number of Shared Access Signatures.

Using a Stored Access Policy

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top