Sat, 10 Apr 2010

Uploading Windows Azure Blobs From Silverlight – Part 1: Shared Access Signatures

screenshot of slupload.cloudapp.net In this series of blog posts, I’ll show you how to use Silverlight to upload blobs directly to Windows Azure storage. At the end of the series, we’ll have a complete solution that supports uploading multiple files of arbitrary size. You can try out the finished sample at http://slupload.cloudapp.net.

Part 1: Shared Access Signatures

Shared Access Signatures are what enable us to use Silverlight to access blob storage directly without compromising the security of our account. In the first part of our series, we’ll cover how Shared Access Signatures are used in http://slupload.cloudapp.net.

Why use Shared Access Signatures?

The typical way to access Windows Azure storage is by constructing a web request, and then signing that web request with the storage account’s shared key. This model works fine when it’s our own trusted code that’s making the call to storage. However, were we to give the shared key to our Silverlight client code, anyone who had access to that Silverlight application would be able to extract the key and use it to take full control of our storage account.

To avoid leaking the storage key, one option is to proxy all requests that come from the client through a web service (which can perform authorization). The web service is then the only code that talks directly to storage. The downside of this approach is that we need to transfer all those bits through a web server. It would be nice to have Silverlight send the data directly to the storage service without leaking our storage credentials.

Shared Access Signatures allow us to separate the code that signs a request from the code that executes it. A Shared Access Signature (SAS) is a set of query string parameters that can be attached to a URL that serve as the authorization for a web request. Contained within the SAS is a policy for which operations are allowed and a signature that proves that the creator of the URL is authorized to perform those operations. By handing this SAS off to our Silverlight client, we pass that authorization down to the client. Now Silverlight can access blob storage directly, but only in the limited ways we granted permission.

Creating a Shared Access Signature

Creating a Shared Access Signature is easy with the latest storage client library. This is the code from the view page on http://slupload.cloudapp.net that creates a list of URLs that are preauthorized for read access:

var readPolicy = new SharedAccessPolicy()
{
    Permissions = SharedAccessPermissions.Read,
    SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromMinutes(10)
};

blobsListView.DataSource =
    from CloudBlob blob in container.ListBlobs(new BlobRequestOptions() { UseFlatBlobListing = true })
    select new Uri(blob.Uri.AbsoluteUri + blob.GetSharedAccessSignature(readPolicy));

The first statement creates the policy, which specifies read-only access for the next ten minutes. The second statement lists all the blobs in a container and creates a list of URIs that have the Shared Access Signature query string appended to them. I use this to data bind the View.aspx page.

To grant write access to a specific blob, I could use the same code as above, except with Write permissions. For http://slupload.cloudapp.net, however, I wanted to let the client upload an arbitrary number of files with arbitrary names. To allow that, I created a Shared Access Signature that’s attached to a container, rather than a specific blob:

ContainerName = Guid.NewGuid().ToString();

var container = blobs.GetContainerReference(ContainerName);
container.Create();

var sas = container.GetSharedAccessSignature(new SharedAccessPolicy()
{
    Permissions = SharedAccessPermissions.Write,
    SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromMinutes(10)
});

The Silverlight client can now append this Shared Access Signature to any blob URI under the specified container. This is the code I run in Default.aspx. The Shared Access Signature is then passed to the Silverlight client via initParams.

More information

For more detail about Shared Access Signatures, read the MSDN documentation, see the feature Ryan and I did on the most recent episode of Cloud Cover, or go back and read my old posts “New Storage Feature: Shared Access Signatures” and “Using Container-Level Access Policies in Windows Azure Storage.” Note that all the code in those posts is now obsolete, but the underlying REST protocol and capabilities haven’t changed.

Read the Whole Series

Read the entire three-part series to see how http://slupload.cloudapp.net was developed:

You can download the full source code for the series as a Visual Studio 2010 RC solution here: http://cdn.blog.smarx.com/files/SilverlightUpload_source.zip.