Friday, March 11, 2011

Cross domain handling on Azure blob storage

This week a customer wanted to access the Azure blob storage from their Silverlight and Flash client applications. However due to the cross-domain restrictions of both technologies, we couldn’t access the blob storage out-of-the-box.

Let’s see how we can solve this and enable full access to blob storage through Silverlight and Flash.

ClientAccessPolicy.xml

When a Silverlight application makes a cross-domain call (other than those that are allowed by default), it first fetches a file called ClientAccessPolicy.xml from the root of the target server. For the blob storage this will be something like http://{namespace}.blob.core.windows.net/ .

Every blob in Windows Azure storage lives within a container, but there’s a special root container which lets us store blobs directly off the root of the domain. This is where we’ll put our ClientAccessPolicy.xml file. The following code creates a publicly readable root container and creates a blob named ClientAccessPolicy.xml within it:

private void CreateSilverlightPolicy()
{
var account= new CloudStorageAccount
(
new StorageCredentialsAccountAndKey("account", "key"), 
new Uri("http://sample.blob.core.windows.net"),
new Uri("http://sample.queue.core.windows.net"),
new Uri("http://sample.table.core.windows.net")
);
var client = account.CreateCloudBlobClient();
blobs.GetContainerReference("$root").CreateIfNotExist();
blobs.GetContainerReference("$root").SetPermissions(
new BlobContainerPermissions() {
PublicAccess = BlobContainerPublicAccessType.Blob
});
var blob = blobs.GetBlobReference("clientaccesspolicy.xml");
blob.Properties.ContentType = "text/xml";
blob.UploadText(@"<?xml version=""1.0"" encoding=""utf-8""?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-methods=""*"" http-request-headers=""*"">
<domain uri=""*"" />
<domain uri=""http://*"" />
</allow-from>
<grant-to>
<resource path=""/"" include-subpaths=""true"" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>");
}
CrossDomain.xml

For the Flash the story is almost the same but instead of adding a clientpolicy file, we need to add a crossdomain.xml file.

private void CreateFlashPolicy()
{
var account= new CloudStorageAccount
(
new StorageCredentialsAccountAndKey("account", "key"), 
new Uri("http://sample.blob.core.windows.net"),
new Uri("http://sample.queue.core.windows.net"),
new Uri("http://sample.table.core.windows.net")
);

var client = account.CreateCloudBlobClient();
blobs.GetContainerReference("$root").CreateIfNotExist();
blobs.GetContainerReference("$root").SetPermissions(
new BlobContainerPermissions()
{
PublicAccess = BlobContainerPublicAccessType.Blob
});
var blob = blobs.GetBlobReference("crossdomain.xml");
blob.Properties.ContentType = "text/xml";
blob.UploadText(@"<?xml version=""1.0"" encoding=""utf-8""?>
<cross-domain-policy>
<allow-access-from domain=""*"" />
</cross-domain-policy>");
}

3 comments:

Anonymous said...

blobs isn't defined.

Jim said...

The content type was holding me up for flash's crossdomain.xml file - thanks for the clean sample code!

Anonymous said...

Thanks for the example, but wanted access to the queue?