Posted in:

I blogged a while ago about how you could create a SAS token to provide access to an Azure Storage blob container. In this post, I want to narrow in on the situation where you want to allow someone to simply upload one file to a container. We’ll see how to create the upload SAS token, and how to upload with the Azure SDK and the REST API.

Creating an Upload Shared Access Signature

The first part is pretty standard – we need a connection string for our storage account from which we can get hold of a CloudBlobContainer for the container we want to upload to.

var connectionString = String.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
    storageAccountName, // your storage account name
    accessKey); // your storage account access key
var storageAccount = CloudStorageAccount.Parse(connectionString);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("my-container");

Next we need to specify the SharedAccessBlobPolicy. We want to be able to Create a file and Write to it, and we also need to reserve a reasonable window of time for the file to be uploaded in.

SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(30);
sasConstraints.Permissions = SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Create;

var blob = container.GetBlockBlobReference("outputfile.txt");
    blob.Uri, blob.GetSharedAccessSignature(sasConstraints));

We then get a blob reference to the filename we want to be able to write to (this file doesn’t need to exist in the container), and then we can use GetSharedAccessSignature in combination with the blob’s Uri to get the full Uri and query string we need to be able to upload.

This results in a SAS Uri looking something like this:

Uploading the Blob

So if we have this Shared Access Signature, how do we actually upload to it? Well, very simply with the Azure SDK. We just need to pass the full SAS Uri into a CloudBlockBlob and then we can use various methods such as UploadFromFile, UploadFromStream or UploadFromByteArray to write to it.

var sas = ""; 
var cloudBlockBlob = new CloudBlockBlob(new Uri(sas));
await cloudBlockBlob.UploadFromFileAsync(@"c:\myfile.txt");

Note that the name of the file cannot be changed from what is specified in the SAS Uri, so the caller is only able to write to this one file in your container.

If you prefer, you can use the Azure Blob storage REST API to upload the content directly:

var client = new HttpClient();
var content = new StringContent("Some content");
content.Headers.Add("x-ms-blob-type", "BlockBlob");
var response = await client.PutAsync(sas, content);