Wednesday, May 23, 2012

Windows Azure – Shared Access Signature for Azure Blob Storage Container

My client has amazing chemical gotcha in his mind. One moment he says something and next moment he asks me to do exactly opposite of it.
Anyways, He asked me to create a Private container in Windows Azure Blob storage and then asked me to give rights to access the container for 1 hour. This is where I came to know about creating Shared Access Signature for Blob Storage. Shared Access Signature can be used in scenarios Azure Blob Storage container is private & still you want to give access to it for certain time duration say 10 days.
Following is the example how Share Access Signature can be created for Windows Azure Blob Storage container and how you can retrieve data from it. For demo purpose I am using development storage. As usual, let’s create a simple cloud service project and add a sample web role in it. Then add a page SharedAccessPolicyDemo.aspx in the web role. I added 2 buttons & few labels on the page to create Shared Access Signature for a private container and access data present in the blob. My final Solution structure is as follows –
Page design is as follow -
I have created a Container in my dev storage from one of the Azure Cloud Storage Explorer as shown below; also added some sample text in a blob –
Now let’s create a shared access policy on this private container to provide public access to the users for 5 minutes.
On the button click write following code –
protected void btnSetPolicy_Click(object sender, EventArgs e)
{
         // Retrieve storage account from connection string
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
                CloudConfigurationManager.GetSetting("StorageConnectionString")); 

            // Create the queue client
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

            // Get a reference to the container for which shared access signature will be created.
            CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");

            // Create a permission policy, consisting of a shared access policy 
            // and a public access setting, and store it on the container. 
            BlobContainerPermissions blobPermissions = new BlobContainerPermissions(); 

            //The shared access policy provides read/write access to the container for 5 minutes.
            blobPermissions.SharedAccessPolicies.Add("mypolicy", new SharedAccessBlobPolicy()
            {
                // This policy goes live 5 min from now.
                SharedAccessStartTime = DateTime.UtcNow,
                SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(5),
                Permissions = SharedAccessBlobPermissions.Read
            });

            // The public access setting off explicitly specifies that the container is private, // so that it can't be accessed anonymously.
            blobPermissions.PublicAccess = BlobContainerPublicAccessType.Off;

            // Set the permission policy on the container.
            container.SetPermissions(blobPermissions);
            lblAccessPolicyString.Text = container.GetSharedAccessSignature(new SharedAccessBlobPolicy(), "mypolicy")
}
Now if I want to read the private container’s contents then I need to fire the query to blob endpoint with above Shared Access Signature.
protected void btnDownload_Click(object sender, EventArgs e)
        {
            // Retrieve storage account from connection-string
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("StorageConnectionString"));
 
            // Create the blob client
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

            // Retrieve reference to a previously created container
            CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");
            string sas = container.GetSharedAccessSignature(new SharedAccessBlobPolicy(), "mypolicy"); 

            // Retrieve reference to a blob named "myblob"
            CloudBlockBlob blob = container.GetBlockBlobReference("myblob");
            string url = blob.Uri.AbsoluteUri + sas;
            string text = null;
 
            using (var reader = new StreamReader(WebRequest.Create(blob.Uri.AbsoluteUri + sas).GetResponse().GetResponseStream()))
            {
                text = reader.ReadToEnd();
            }

            lblBlobContents.Text = text;
        }


The label will have blob contents and final output is as given below –

Now if we try to browse the URL directly in browser after expiry time of 5 minutes then I get following error – “The remote server returned an error: (403) Forbidden”
OR
Signature not valid in the specified time frame
Hence once my Shared Access Policy is expired the container information will not be accessible.
Hope it helps.
Cheers…
Happy Blobbing!!!

No comments:

Post a Comment