Статьи

Пересмотр подписи общего доступа Windows Azure

В этом сообщении мы поговорим о функциональности подписи общего доступа (SAS) в Windows Azure . Стив Маркс ( @smarx ) несколько лет назад написал отличные посты в блогах на эту тему, которые вы можете прочитать здесь: http://blog.smarx.com/posts/shared-access-signatures-are-easy-these-days , http://blog.smarx.com/posts/uploading-windows-azure-blobs-from-silverlight-part-1-shared-access-signatures . Однако многое изменилось с тех пор, как Стив написал посты, и я подумал, что было бы полезно написать об этом, принимая во внимание эти новые вещи (отсюда и слово «Пересмотр» в названии.:)). Этот блог начнется с базового объяснения сигнатуры общего доступа и цели, для которой он служит, а затем я покажу вам некоторый код для выполнения некоторых основных операций с хранилищем Windows Azure, особенно с хранилищем BLOB-объектов.

Теперь, когда повестка дня установлена, давайте начнем :)

Общая подпись (SAS) — почему и что?

В этом разделе описывается, почему нам нужен SAS и что это такое. Если вы знакомы с этими концепциями, пожалуйста, не стесняйтесь пропустить этот раздел, иначе читайте дальше!

Зачем?

Сначала давайте разберемся, зачем нам нужен SAS. Как вы уже знаете, доступ к хранилищу Windows Azure не является анонимным. Скорее вам понадобится « ключ учетной записи » для доступа к ресурсам в учетной записи хранения. Этот ключ учетной записи (на самом деле существует 2 ключа учетной записи — основной и дополнительный) автоматически создается для вас хранилищем Windows Azure, и вы также получаете возможность восстановить ключ по требованию. Проблема с доступом на основе ключа учетной записи заключается в том, что ключ учетной записи предоставляет привилегии «Администратор» для данной учетной записи хранения. Любой, кто имеет доступ к этому ключу учетной записи, может выполнить любую разрешенную операцию с учетной записью хранения. Это, очевидно, проблема безопасности, и нужно всегда стараться хранить секретный ключ учетной записи и защищать его с полным усердием.

Однако существуют сценарии, в которых вы хотите предоставить пользователю (который может быть партнером, клиентом и т. Д.) Ограниченный доступ к вашей учетной записи хранения. Вы бы хотели, чтобы этот пользователь выполнял только несколько операций, и это тоже в течение ограниченного периода времени. Очевидно, что передача этого пользователя ключу вашей учетной записи не принесет вам пользы, потому что это сделает пользователя администратором. Ответом на эту проблему является SAS. SAS позволяет вам предоставить временный доступ к частным ресурсам в вашей учетной записи хранения .

Недавно я читал книгу Билла Уайлдера ( @codingoutloud ) о шаблонах облачной архитектуры, и он очень хорошо объяснил эту концепцию, используя аналогию « Ключа от машины ». Если вы планируете создавать облачное приложение в Windows Azure, я настоятельно рекомендую сначала прочитать эту книгу, прежде чем писать код.

Какая?

Проще говоря, SAS — это URL (или, скорее, его часть). Вы, как создатель SAS, определяете срок действия SAS и то, что пользователь, обладающий этим SAS, может делать с ресурсами, защищенными SAS . Например, вы можете определить SAS, который позволит пользователю загружать файл в контейнер больших двоичных объектов в вашей учетной записи хранения и истекает через, скажем, 1 час. В течение того часа, в течение которого действует SAS, любой пользователь, имеющий доступ к этому SAS, сможет загрузить файлы в контейнер BLOB-объектов. После этого часа ссылка станет бесполезной.

Вы можете создать SAS для ресурсов BLOB-объектов (контейнеры BLOB-объектов и BLOB-объектов), ресурсов таблицы (таблицы и диапазоны PartitionKey / RowKey) и ресурсов очереди (очереди и сообщения). Вы можете дать одно или несколько разрешений на операции CRUD в SAS. Наконец, вы можете определить начальную и конечную дату, для которой действует SAS.

С хранилищем больших двоичных объектов вы можете создать SAS для контейнера больших двоичных объектов или большого двоичного объекта. В следующей таблице приведены разрешения и цели, которые они служат для различных ресурсов BLOB-объектов:

Тип разрешения

Контейнер BLOB-объектов

капля

Читать

Не применяется к контейнеру BLOB-объектов.

Дает возможность читать содержимое блоба. Также дает возможность читать метаданные и свойства большого двоичного объекта.

Написать

Дает возможность загрузить один или несколько BLOB-объектов в контейнер BLOB-объектов. Также дает возможность обновлять свойства, метаданные и создавать снимки большого двоичного объекта.

Дайте возможность загрузить новый BLOB-объект (с тем же именем) или перезаписать существующий BLOB-объект (с тем же именем). Также дает возможность обновлять свойства, метаданные и создавать снимки большого двоичного объекта.

Список

Перечисляет BLOB-объекты в контейнере BLOB-объектов.

Не применимо к каплям.

Удалить

Не применяется к контейнеру BLOB-объектов.

Дает возможность удалить блоб.

С помощью хранилища таблиц вы можете создать SAS для таблицы или диапазонов сущностей в таблице. Для диапазонов сущностей можно указать диапазоны PartitionKey / RowKey. В следующей таблице приведены разрешения и цели, которые они служат для различных ресурсов таблицы:

Тип разрешения

Стол

Диапазоны сущностей (PartitionKey / RowKey Ranges)

запрос

Дает возможность запросить таблицу.

Дает возможность запрашивать таблицу, но запрос ограничен диапазоном сущностей, указанным в SAS.

Добавить

Дает возможность добавить объект в таблицу.

Дает возможность добавить объект в таблицу при условии, что значения объекта PartitionKey / RowKey находятся в пределах диапазона.

Обновить

Дает возможность обновить сущность в таблице.

Дает возможность обновить сущность в таблице при условии, что значения сущности PartitionKey / RowKey находятся в пределах диапазона.

Удалить

Дает возможность удалить сущность из таблицы.

Дает возможность удалить объект из таблицы при условии, что значения объекта PartitionKey / RowKey находятся в пределах диапазона.

С хранилищем очереди вы можете создать SAS для очереди. В следующей таблице приведены разрешения и цели, которые они служат для ресурсов очереди:

Тип разрешения

Очередь

Читать или заглядывать

Дает возможность заглядывать в сообщения в очереди. Обратите внимание, что функция просмотра сообщений позволяет пользователю просматривать сообщения в режиме «Только для чтения» и не влияет на видимость сообщений.

Добавить

Дает возможность добавлять сообщения в очередь.

Процесс

Дает возможность получать сообщения из очереди. Обратите внимание, что это даст пользователям возможность удалять сообщения, а также изменяет видимость сообщений.

Обновить

Дает возможность обновить сообщение в очереди. Для этого разрешения требуется разрешение Процесс.

Еще несколько комментариев о SAS, прежде чем мы перейдем к коду :).

Отзывной SAS

Вы можете сделать SAS отзывным. Это означает, что вы можете сделать SAS недействительным до истечения срока его действия. Это достигается с помощью так называемой политики доступа к контейнеру BLOB-объектов . Когда вы создаете SAS с использованием политики доступа к контейнеру больших двоичных объектов, чтобы отозвать SAS, вы можете просто изменить идентификатор политики доступа или удалить эту политику доступа все вместе. На момент написания блоб-контейнер может иметь максимум 5 политик доступа.

Аноним SAS

Когда SAS создается без политики доступа к контейнеру BLOB-объектов, он называется анонимным SAS. Поскольку они не могут быть отозваны, при обращении с этим SAS необходимо соблюдать осторожность. Вообще говоря, вы должны попытаться создать анонимный SAS очень короткой продолжительности.

Никогда не истекает SAS

Хотя это и не рекомендуемая практика , возможно создать SAS, который никогда не истекает. Для этого вы не указываете дату окончания срока действия при создании SAS. В более ранней версии службы хранения срок действия только отзываемого SAS никогда не истекает, а анонимный SAS действителен только в течение 1 часа. Однако с помощью последней версии службы хранения можно создавать анонимные SAS с неограниченным сроком действия.

Дата и время начала SAS

Обратите внимание, что дата и время начала и окончания SAS указаны в UTC. Кроме того, они проверены в Windows Azure. Возможно, существует несоответствие между временем на локальном компьютере (где генерируется SAS) и временем в Windows Azure. Чтобы противостоять этой проблеме, как правило, рекомендуется установить время запуска SAS, вычитая примерно 5-10 минут от времени вашего локального компьютера (в формате UTC). Например:

var sas = blobContainer.GetSharedAccessSignature(new SharedAccessBlobPolicy()
    {
        Permissions = permission,
        SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5),//SAS Start time is back by 5 minutes to take clock skewness into consideration
        SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(15),
    });

MSDN имеет хорошую документацию о функциональности SAS и многое другое, что я рекомендую вам прочитать: http://msdn.microsoft.com/en-us/library/windowsazure/ee393343.aspx

Код!

Хорошо, хватит говорить! Давайте посмотрим код. В приведенных ниже примерах кода я использовал последнюю версию клиентской библиотеки хранилища (2.0.4 на момент написания этой статьи). Я использовал клиентскую библиотеку хранилища для создания URI SAS, однако вы можете использовать такие инструменты, как Cloud Storage Studio, которая поддерживает эту функцию. Затем, используя этот SAS URI, я собираюсь продемонстрировать, как вы собираетесь выполнять некоторые общие операции с хранилищем больших двоичных объектов. Для каждой операции я включил, как вы собираетесь выполнять операцию с использованием клиентской библиотеки хранилища, а также собираетесь ли вы сделать это, используя REST API напрямую, используя HttpWebRequest / HttpWebResponse. Общая тема с клиентской библиотекой хранилища заключается в том, что она позволяет создавать экземпляры CloudBlobContainer и CloudBlockBlob.(В этом посте я сосредоточился только на блочных объектах), используя только SAS URI. Опять же для простоты я просто использовал анонимный SAS и не использовал политику доступа к контейнеру BLOB-объектов для создания URI SAS.

Вспомогательные функции

Я создал две вспомогательные функции для создания SAS на контейнере BLOB-объектов и BLOB-объектах. Для простоты я жестко запрограммировал время начала и окончания действия SAS:

/// <summary>
/// Creates a SAS URI for the blob container.
/// </summary>
/// <param name="blobContainer"></param>
/// <param name="permission"></param>
/// <returns></returns>
static string GetSaSForBlobContainer(CloudBlobContainer blobContainer, SharedAccessBlobPermissions permission)
{
    var sas = blobContainer.GetSharedAccessSignature(new SharedAccessBlobPolicy()
        {
            Permissions = permission,
            SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5),//SAS Start time is back by 5 minutes to take clock skewness into consideration
            SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(15),
        });
    return string.Format(CultureInfo.InvariantCulture, "{0}{1}", blobContainer.Uri, sas);
}
/// <summary>
/// Creates a SAS URI for the blob.
/// </summary>
/// <param name="blob"></param>
/// <param name="permission"></param>
/// <returns></returns>
static string GetSaSForBlob(CloudBlockBlob blob, SharedAccessBlobPermissions permission)
{
    var sas = blob.GetSharedAccessSignature(new SharedAccessBlobPolicy()
    {
        Permissions = permission,
        SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5),
        SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(15),
    });
    return string.Format(CultureInfo.InvariantCulture, "{0}{1}", blob.Uri, sas);
}

Листинг BLOB-объектов

Вот код для перечисления больших двоичных объектов в контейнере больших двоичных объектов. Для перечисления больших двоичных объектов разрешение « Список » должно быть определено в SAS.

Использование клиентской библиотеки хранилища

/// <summary>
/// List blobs in a blob container using storage client library.
/// </summary>
/// <param name="blobContainerSasUri"></param>
static void ListBlobsWithStorageClientLibrary(string blobContainerSasUri)
{
    CloudBlobContainer blobContainer = new CloudBlobContainer(new Uri(blobContainerSasUri));
    var blobs = blobContainer.ListBlobs(null, true);
    foreach (var blob in blobs)
    {
        Console.WriteLine(blob.Uri);
    }
}

Использование REST API

/// <summary>
/// List blobs in a blob container using REST API.
/// </summary>
/// <param name="blobContainerSasUri"></param>
static void ListBlobsWithRestAPI(string blobContainerSasUri)
{
    string requestUri = string.Format(CultureInfo.InvariantCulture, "{0}&comp=list", blobContainerSasUri);
    HttpWebRequest request = (HttpWebRequest) WebRequest.Create(requestUri);
    request.Method = "GET";
    using (HttpWebResponse resp = (HttpWebResponse) request.GetResponse())
    {
        using (Stream s = resp.GetResponseStream())
        {
            using (StreamReader reader = new StreamReader(s, true))
            {
                string blobsData = reader.ReadToEnd();
                Console.WriteLine(blobsData);
            }
        }
    }
}

Вы должны добавить « & comp = list » в URI для перечисления контейнеров BLOB-объектов. Также вывод XML.

Я мог бы просто взять URI (в переменной requestUri выше) и вставить его в адресное окно браузера и увидеть список больших двоичных объектов в контейнере больших двоичных объектов. Смотрите скриншот ниже для примера.

образ

Загрузить BLOB-объекты

Вот код для загрузки BLOB-объекта в контейнер BLOB-объектов. Для загрузки большого двоичного объекта вы можете создать SAS с разрешением « Запись » для контейнера больших двоичных объектов или большого двоичного объекта. Капля не должна присутствовать в контейнере капли. Если блоб отсутствует, он будет создан, в противном случае он будет перезаписан.

Использование клиентской библиотеки хранилища

/// <summary>
/// Uploads a blob in a blob container where SAS permission is defined on a blob container using storage client library.
/// </summary>
/// <param name="blobContainerSasUri"></param>
static void UploadBlobWithStorageClientLibrarySasPermissionOnBlobContainer(string blobContainerSasUri)
{
    CloudBlobContainer blobContainer = new CloudBlobContainer(new Uri(blobContainerSasUri));
    CloudBlockBlob blob = blobContainer.GetBlockBlobReference("sample.txt");
    string sampleContent = "This is sample text.";
    using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(sampleContent)))
    {
        blob.UploadFromStream(ms);
    }
}
/// <summary>
/// Uploads a blob in a blob container where SAS permission is defined on a blob using storage client library.
/// </summary>
/// <param name="blobSasUri"></param>
static void UploadBlobWithStorageClientLibrarySasPermissionOnBlob(string blobSasUri)
{
    CloudBlockBlob blob = new CloudBlockBlob(new Uri(blobSasUri));
    string sampleContent = "This is sample text.";
    using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(sampleContent)))
    {
        blob.UploadFromStream(ms);
    }
}

Использование REST API

/// <summary>
/// Uploads a blob in a blob container where SAS permission is defined on a blob container using REST API.
/// </summary>
/// <param name="blobContainerSasUri"></param>
static void UploadBlobWithRestAPISasPermissionOnBlobContainer(string blobContainerSasUri)
{
    string blobName = "sample.txt";
    string sampleContent = "This is sample text.";
    int contentLength = Encoding.UTF8.GetByteCount(sampleContent);
    string queryString = (new Uri(blobContainerSasUri)).Query;
    string blobContainerUri = blobContainerSasUri.Substring(0, blobContainerSasUri.Length - queryString.Length);
    string requestUri = string.Format(CultureInfo.InvariantCulture, "{0}/{1}{2}", blobContainerUri, blobName, queryString);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
    request.Method = "PUT";
    request.Headers.Add("x-ms-blob-type", "BlockBlob");
    request.ContentLength = contentLength;
    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(Encoding.UTF8.GetBytes(sampleContent), 0, contentLength);
    }
    using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
    {
         
    }
}

При работе с REST API необходимо указать заголовок запроса « x-ms-blob-type ». Для блочных BLOB-объектов его значение должно быть « BlockBlob », а для блочных страниц — « PageBlob ».

Загрузить Blobs в блоках

Вот код, если вы хотите загрузить блоб, разбив его на блоки. Для загрузки большого двоичного объекта вы можете создать SAS с разрешением « Запись » для контейнера больших двоичных объектов или большого двоичного объекта. Капля не должна присутствовать в контейнере капли. Если блоб отсутствует, он будет создан, в противном случае он будет перезаписан.

Использование клиентской библиотеки хранилища

/// <summary>
/// Uploads a blob by splitting into blocks in a blob container where SAS permission is defined on a blob container using storage client library.
/// </summary>
/// <param name="blobContainerSasUri"></param>
static void UploadBlobInBlocksWithStorageClientLibrarySasPermissionOnBlobContainer(string blobContainerSasUri)
{
    CloudBlobContainer blobContainer = new CloudBlobContainer(new Uri(blobContainerSasUri));
    CloudBlockBlob blob = blobContainer.GetBlockBlobReference(Guid.NewGuid().ToString() + ".txt");
    List<string> blockIds = new List<string>();
    for (int i = 0; i < 10; i++)
    {
        string sampleContent = string.Format(CultureInfo.InvariantCulture, "Line {0}: This is sample text.\r\n", i);
        string blockId = i.ToString("d4");
        blockIds.Add(blockId);
        using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(sampleContent)))
        {
            blob.PutBlock(blockId, ms, null);
        }
    }
    blob.PutBlockList(blockIds);
}
/// <summary>
/// Uploads a blob by splitting into blocks in a blob container where SAS permission is defined on a blob using storage client library.
/// </summary>
/// <param name="blobSasUri"></param>
static void UploadBlobInBlocksWithStorageClientLibrarySasPermissionOnBlob(string blobSasUri)
{
    CloudBlockBlob blob = new CloudBlockBlob(blobSasUri);
    List<string> blockIds = new List<string>();
    for (int i = 0; i < 10; i++)
    {
        string sampleContent = string.Format(CultureInfo.InvariantCulture, "Line {0}: This is sample text.\r\n", i);
        string blockId = i.ToString("d4");
        blockIds.Add(blockId);
        using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(sampleContent)))
        {
            blob.PutBlock(blockId, ms, null);
        }
    }
    blob.PutBlockList(blockIds);
}

Использование REST API

/// <summary>
/// Uploads a blob by splitting into blocks in a blob container where SAS permission is defined on a blob container using REST API.
/// </summary>
/// <param name="blobContainerSasUri"></param>
static void UploadBlobInBlocksWithRestAPISasPermissionOnBlobContainer(string blobContainerSasUri)
{
    string blobName = Guid.NewGuid().ToString() + ".txt";
    string queryString = (new Uri(blobContainerSasUri)).Query;
    string blobContainerUri = blobContainerSasUri.Substring(0, blobContainerSasUri.Length - queryString.Length);
    List<string> blockIds = new List<string>();
    for (int i = 0; i < 10; i++)
    {
        string sampleContent = string.Format(CultureInfo.InvariantCulture, "Line {0}: This is sample text.\r\n", i);
        string blockId = i.ToString("d4");
        blockIds.Add(blockId);
        int contentLength = Encoding.UTF8.GetByteCount(sampleContent);
        string requestUri = string.Format(CultureInfo.InvariantCulture, "{0}/{1}{2}&comp=block&blockid={3}", blobContainerUri, blobName, queryString, Convert.ToBase64String(Encoding.UTF8.GetBytes(blockId)));
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
        request.Method = "PUT";
        request.ContentLength = contentLength;
        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(Encoding.UTF8.GetBytes(sampleContent), 0, contentLength);
        }
        using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
        {
 
        }
    }
    string commitBlockListRequestBodyFormat = @"<?xml version=""1.0"" encoding=""utf-8"" ?><BlockList>{0}</BlockList>";
 
    string blockListReuestBodyFormat = "<Latest>{0}</Latest>";
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < blockIds.Count; i++)
    {
        sb.AppendFormat(CultureInfo.InvariantCulture, blockListReuestBodyFormat,
                        Convert.ToBase64String(Encoding.UTF8.GetBytes(blockIds[i])));
    }
    string requestPayLoad = string.Format(CultureInfo.InvariantCulture, commitBlockListRequestBodyFormat,
                                          sb.ToString());
    int contentLengthForCommitBlockList = Encoding.UTF8.GetByteCount(requestPayLoad);
    string requestUriForCommitBlockList = string.Format(CultureInfo.InvariantCulture, "{0}/{1}{2}&comp=blockList", blobContainerUri, blobName, queryString);
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requestUriForCommitBlockList);
    req.Method = "PUT";
    req.ContentLength = contentLengthForCommitBlockList;
    using (Stream requestStream = req.GetRequestStream())
    {
        requestStream.Write(Encoding.UTF8.GetBytes(requestPayLoad), 0, contentLengthForCommitBlockList);
    }
    using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
    {
 
    }
}
/// Uploads a blob by splitting into blocks in a blob container where SAS permission is defined on a blob using REST API.
/// </summary>
/// <param name="blobSasUri"></param>
static void UploadBlobInBlocksWithRestAPISasPermissionOnBlob(string blobSasUri)
{
    List<string> blockIds = new List<string>();
    for (int i = 0; i < 10; i++)
    {
        string sampleContent = string.Format(CultureInfo.InvariantCulture, "Line {0}: This is sample text.\r\n", i);
        string blockId = i.ToString("d4");
        blockIds.Add(blockId);
        int contentLength = Encoding.UTF8.GetByteCount(sampleContent);
        string requestUri = string.Format(CultureInfo.InvariantCulture, "{0}&comp=block&blockid={1}", blobSasUri, Convert.ToBase64String(Encoding.UTF8.GetBytes(blockId)));
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
        request.Method = "PUT";
        request.ContentLength = contentLength;
        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(Encoding.UTF8.GetBytes(sampleContent), 0, contentLength);
        }
        using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
        {
 
        }
    }
    string commitBlockListRequestBodyFormat = @"<?xml version=""1.0"" encoding=""utf-8"" ?><BlockList>{0}</BlockList>";
 
    string blockListReuestBodyFormat = "<Latest>{0}</Latest>";
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < blockIds.Count; i++)
    {
        sb.AppendFormat(CultureInfo.InvariantCulture, blockListReuestBodyFormat,
                        Convert.ToBase64String(Encoding.UTF8.GetBytes(blockIds[i])));
    }
    string requestPayLoad = string.Format(CultureInfo.InvariantCulture, commitBlockListRequestBodyFormat,
                                          sb.ToString());
    int contentLengthForCommitBlockList = Encoding.UTF8.GetByteCount(requestPayLoad);
    string requestUriForCommitBlockList = string.Format(CultureInfo.InvariantCulture, "{0}&comp=blockList", blobSasUri);
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requestUriForCommitBlockList);
    req.Method = "PUT";
    req.ContentLength = contentLengthForCommitBlockList;
    using (Stream requestStream = req.GetRequestStream())
    {
        requestStream.Write(Encoding.UTF8.GetBytes(requestPayLoad), 0, contentLengthForCommitBlockList);
    }
    using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
    {
 
    }
}

При работе с REST API для помещения блоков необходимо указать « comp = block » и кодированный в Base64 идентификатор блока в URI запроса . Для размещения списка блокировки необходимо указать « comp = blockList » в URI запроса.

Скачать Blobs

Вот код для загрузки BLOB-объекта из контейнера BLOB-объектов. Для загрузки большого двоичного объекта в SAS должно быть указано разрешение « Чтение ».

Использование клиентской библиотеки хранилища

/// <summary>
/// Downloads a blob from a blob cobtainer using storage client library.
/// </summary>
/// <param name="blobSasUri"></param>
static void DownloadBlobWithStorageClientLibrary(string blobSasUri)
{
    CloudBlockBlob blob = new CloudBlockBlob(new Uri(blobSasUri));
    using (MemoryStream ms = new MemoryStream())
    {
        blob.DownloadToStream(ms);
        byte[] data = new byte[ms.Length];
        ms.Position = 0;
        ms.Read(data, 0, data.Length);
        string blobContents = Encoding.UTF8.GetString(data);
        Console.WriteLine(blobContents);
    }
}

Использование REST API

/// <summary>
/// Downloads a blob from a blob cobtainer using REST API.
/// </summary>
/// <param name="blobSasUri"></param>
static void DownloadBlobWithRestAPI(string blobSasUri)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(blobSasUri);
    request.Method = "GET";
    using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
    {
        using (Stream s = resp.GetResponseStream())
        {
            using (StreamReader reader = new StreamReader(s, true))
            {
                string blobData = reader.ReadToEnd();
                Console.WriteLine(blobData);
            }
        }
    }
}

Удаление BLOB-объектов

Вот код для удаления BLOB-объекта из контейнера BLOB-объектов. Для операции удаления в SAS должно быть определено разрешение « Удалить ».

Использование клиентской библиотеки хранилища

/// <summary>
/// Deletes a blob from a blob cobtainer using storage client library.
/// </summary>
/// <param name="blobSasUri"></param>
static void DeleteBlobWithStorageClientLibrary(string blobSasUri)
{
    CloudBlockBlob blob = new CloudBlockBlob(new Uri(blobSasUri));
    blob.Delete();
}

Использование REST API

/// <summary>
/// Deletes a blob from a blob cobtainer using REST API.
/// </summary>
/// <param name="blobSasUri"></param>
private static void DeleteBlobWithRestAPI(string blobSasUri)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(blobSasUri);
    request.Method = "DELETE";
    using (HttpWebResponse resp = (HttpWebResponse) request.GetResponse())
    {
         
    }
}

Резюме

Вот именно для этого поста. Я мог бы сделать больше и включить больше примеров, но они должны дать вам представление о том, как использовать SAS для выполнения различных операций. Может быть, в другом посте я покажу некоторые функции, связанные с таблицами и очередями с помощью SAS. Я надеюсь, что вы нашли этот пост полезным. Если вы обнаружите какие-либо проблемы с этим сообщением, пожалуйста, дайте мне знать, и я постараюсь исправить их как можно скорее. Не стесняйтесь предоставлять свои комментарии ниже.

Удачного кодирования !!!