video : Cómo acceder al Storage de Azure Utilizando REST | WinRT | C#

Avanzado

Esto puede ser muy útil cuando no puedes usar Azure SDK o cuando no hay una versión del SDK disponible para el lenguaje o plataforma que manejas.

El video se hizo en WinRT + C# pero el mecanismo puede ser imitado desde otros lenguajes y frameworks.

En este video también se muestra como construir el header de autorización incluyendo como crear la firma [ signature ] con el Storage Key.

Acá el código fuente

 using System;  
using System.Globalization;  
using System.IO;  
using System.Net.Http;  
using System.Net.Http.Headers;  
using System.Threading.Tasks;  
using Windows.Security.Cryptography;  
using Windows.Security.Cryptography.Core;

namespace App5.Storage  
{
    public class BlockBlobStorage
    {
        private const string X_MS_BLOCK_BLOB = "BlockBlob";
        private const string X_MS_VERSION = "2012-02-12";
        public string Account { get; set; }
        public string Key { get; set; }

        public BlockBlobStorage(string account, string key)
        {
            Account = account;
            Key = key;
        }

        public async Task<HttpResponseMessage> UploadAsync(string blobname, Stream stream,
            string mimetype = "application/octect-stream")
        {
            var httpClient = new HttpClient();
            var content = new StreamContent(stream);
            var tmpdate = RFC1123DateTime;
            //headers
            content.Headers.ContentType = new MediaTypeHeaderValue(mimetype);
            httpClient.DefaultRequestHeaders.Add("x-ms-date", tmpdate);
            httpClient.DefaultRequestHeaders.Add("x-ms-blob-type", X_MS_BLOCK_BLOB);
            httpClient.DefaultRequestHeaders.Add("x-ms-version", X_MS_VERSION);

            string signature = CreateSignature(
                HTTPVerb: "PUT",
                ContentLength: stream.Length.ToString(),
                ContentType: mimetype,
                CanonicalizedHeaders: "x-ms-blob-type:BlockBlob\nx-ms-date:" + tmpdate + "\nx-ms-version:2012-02-12",
                CanonicalizedResource: string.Format("/{0}/{1}", Account, blobname)
                );

            httpClient.DefaultRequestHeaders.Add("Authorization",
                string.Format("SharedKey {0}:{1}", Account, signature));

            return await httpClient.PutAsync(
                string.Format("https://{0}.blob.core.windows.net/{1}", Account, blobname),
                content
                );
        }

        private string CreateSignature(
            string HTTPVerb = "",
            string ContentEncoding = "",
            string ContentLanguage = "",
            string ContentLength = "",
            string ContentMD5 = "",
            string ContentType = "",
            string Date = "",
            string IfModifiedSince = "",
            string IfMatch = "",
            string IfNoneMatch = "",
            string IfUnmodifiedSince = "",
            string Range = "",
            string CanonicalizedHeaders = "",
            string CanonicalizedResource = ""
            )
        {
            var sumstring = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n{6}\n{7}\n{8}\n{9}\n{10}\n{11}\n{12}\n{13}",
                HTTPVerb, ContentEncoding, ContentLanguage, ContentLength, ContentMD5,
                ContentType, Date, IfModifiedSince, IfMatch, IfNoneMatch, IfUnmodifiedSince,
                Range, CanonicalizedHeaders, CanonicalizedResource
                );

            return ComputeHMAC_SHA256(sumstring);
        }

        private string ComputeHMAC_SHA256(string input)
        {
            var alg = MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA256");
            //preparar input
            var inputBuffer = CryptographicBuffer.ConvertStringToBinary(input, BinaryStringEncoding.Utf8);
            //preparar key
            var keybuffer = CryptographicBuffer.DecodeFromBase64String(Key);
            var hmacKey = alg.CreateKey(keybuffer);

            var signbuffer = CryptographicEngine.Sign(hmacKey, inputBuffer);
            return CryptographicBuffer.EncodeToBase64String(signbuffer);
        }

        public string RFC1123DateTime { get { return DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture); } }
    }
}

Ejemplo de uso

 var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/chocorramo.jpg"));  
            var stream = await file.OpenStreamForReadAsync();

            var blobUploader = new BlockBlobStorage("jk4freeusage", "Yk4KMu8b0FAzCuqJf4y3j5XSslLxqXYndfkReWg8YkLFVaQOzF1Ga4eAE8jy+rEyOMh9RP228rz0SB2uwkoOoQ==");
            var rta = await blobUploader.UploadAsync("imagenes/chocorramo.jpg", stream, mimetype: "image/jpeg");