Статьи

Совместное использование частных BLOB-объектов с Windows Azure SDK для PHP

В последние пару недель я потратил немало времени, чтобы больше узнать о хранилище BLOB-объектов Windows Azure. Я хотел ответить на два вопроса: «Как я могу поделиться личными BLOB с другими?» и «Как получить доступ к закрытым BLOB-объектам, которыми другие поделились со мной?» Краткий ответ на оба вопроса — «Использовать подписи общего доступа », хотя я не уверен, что « подпись общего доступа » — это фраза, обычно используемая вне кругов .NET. В этом посте я отвечу на оба вопроса, которые я сам для себя задал, и проясню любой вопрос о фразе «подпись общего доступа».

Примечание . Поскольку API хранилища BLOB-объектов является API REST (как и для таблиц и очередей Azure), код в этом посте должен выполняться на любой платформе.

Если вы не использовали Windows Azure SDK для PHP для доступа к хранилищу BLOB-объектов Windows Azure, я предлагаю начать с чтения этого поста: Доступ к хранилищу BLOB-объектов Windows Azure из PHP . Обратите пристальное внимание на раздел « Создание контейнера и настройка ACL », так как в оставшейся части этого поста предполагается, что у вас есть контейнеры и большие двоичные объекты, которые являются «частными».

Что такое «подпись общего доступа»?

«Общая подпись доступа» — это базовый 64- хэш- кодированный код аутентификации сообщений (HMAC)который добавляется в качестве параметра строки запроса к URL-адресу. Используя закрытый ключ учетной записи хранения, вы «подписываете» согласованную строку (состоящую из элементов самого URL-адреса) и присоединяете ее в качестве параметра запроса к URL-адресу. Когда ресурс запрашивается с подписанным URL-адресом, поставщик ресурса восстанавливает согласованную строку из URL-адреса и создает подпись с вашим закрытым ключом (поскольку поставщик ресурсов, в данном случае Windows Azure, знает ваш закрытый ключ). Если подпись совпадает с подписью, указанной в URL-адресе, запрос ресурса удовлетворяется, в противном случае он отклоняется. Если вы использовали Amazon Simple Storage Service (S3), вы, вероятно, знакомы с подписью URL-адресов, чтобы сделать частные ресурсы S3 доступными (по крайней мере, временно). Аналогичный процесс используется для BLOB-объектов Windows Azure.

Подписанный URL выглядит следующим образом (очевидно, без разрывов строк и пробелов):

http://bswanstorage.blob.core.windows.net/pics/Desert.jpg?
     st=2011-11-08T20%3A03%3A35.0000000Z&
     se=2011-11-08T20%3A53%3A35.0000000Z&
     sr=b&
     sp=r&
     sig=R2G7CL1C0qOSfhMieEurr5THiVJYPVy7wj1OrA6120s%3D

Этот URL предоставляет доступ для чтения к BLOB- объекту Desert.jpg в контейнере pics с 2011-11-08 в 20:03:35 до 2011-11-08 в 20:53:35. Подпись общего доступа ( R2G7CL1C0qOSfhMieEurr5THiVJYPVy7wj1OrA6120s% 3D ) была создана путем подписания этой строки:

r 2011-11-08T20:03:35.0000000Z 2011-11-08T20:53:35.0000000Z /bswanstorage/pics/Desert.jpg

Для получения более подробной информации о сигнатурах общего доступа см. Создание подписи общего доступа . (Код в этой статье — .NET, но он также содержит интересную справочную информацию об управлении доступом к BLOB-объектам.)

Как поделиться приватными BLOB-объектами и контейнерами

К счастью, Windows Azure SDK для PHP делает создание подписей общего доступа очень простым: класс Microsoft_WindowsAzure_Storage_Blob имеет метод generateSharedAccessUrl . Метод generateSharedAccessUrl принимает до 7 параметров, которые…

  1. $ containerName: имя контейнера
  2. $ blobName: имя блоба
  3. $ resource: подписанный ресурс — контейнер (c) — blob (b)
  4. $ permissions: подписанные разрешения — чтение (r), запись (w), удаление (d) и список (l)
  5. $ start: время, когда подпись общего доступа становится действительной.
  6. $ expiry: время, когда подпись общего доступа становится недействительной.
  7. $ идентификатор: подписанный идентификатор

Итак, чтобы создать пример URL в приведенном выше разделе (который делает BLOB-объект читаемым в течение 50 минут), я сделал следующее:

require_once 'Microsoft/WindowsAzure/Storage/Blob.php';
 define("STORAGE_ACCOUNT_NAME", "storage_account_name");
 define("STORAGE_ACCOUNT_KEY", "storage_account_key");
 
 $storageClient = new Microsoft_WindowsAzure_Storage_Blob('blob.core.windows.net', STORAGE_ACCOUNT_NAME, STORAGE_ACCOUNT_KEY);
 
 $sharedAccessUrl = $storageClient->generateSharedAccessUrl(
                      'pics',
                      'Desert.jpg',
                      'b', 
                      'r',
                     $storageClient ->isoDate(time()),
                      $storageClient ->isoDate(time() + 3000)
                     );

Если вы хотите создать URL-адрес, относящийся к контейнеру, оставьте параметр $ blobName пустым. Так, например, этот код производит URL , который делает содержимое фото контейнера неперечислимо:

require_once 'Microsoft/WindowsAzure/Storage/Blob.php';
 define("STORAGE_ACCOUNT_NAME", "storage_account_name");
 define("STORAGE_ACCOUNT_KEY", "storage_account_key");
 
 $storageClient = new Microsoft_WindowsAzure_Storage_Blob('blob.core.windows.net', STORAGE_ACCOUNT_NAME, STORAGE_ACCOUNT_KEY);
  
 $sharedAccessUrl = $storageClient->generateSharedAccessUrl(
                     'pics',
                     '',
                     'c', 
                     'l',
                     $storageClient ->isoDate(time()),
                     $storageClient ->isoDate(time() + 3000)
                    );

После создания этих подписанных URL-адресов вы можете передать их пользователям, чтобы они могли временно получить доступ к вашим ресурсам хранилища BLOB-объектов. Это, конечно, вызывает вопрос: «Как мне использовать один из этих подписанных URL-адресов?»

Как получить доступ к общим закрытым BLOB-объектам и контейнерам

В случае с большим двоичным объектом (как в первом примере выше) получить к нему доступ просто, вставив подписанный URL-адрес в браузер. Пока подпись действительна (и URL-адрес используется в течение указанного времени), рассматриваемый большой двоичный объект должен быть доступен.

Тем не менее, как насчет второго примера выше? В этом примере сгенерированный URL-адрес предоставляет пользователю разрешение на просмотр содержимого контейнера. Простое вставление URL-адреса в браузер не приведет к выводу содержимого контейнера, поэтому как использовать URL-адрес? Windows Azure SDK предоставляет способ получения разрешений, предоставленных в подписанном URL-адресе, и их использования.

Чтобы составить список больших двоичных объектов в контейнере, мне нужно будет использовать метод listBlobs в классе Microsoft_WindowsAzure_Storage_Blob , но чтобы получить разрешение на перечисление больших двоичных объектов, мне придется использовать метод setCredentials и метод setPermissionSet . Обратите внимание, что все, что мне нужно сделать после вызова метода setCredentials, это передать URL-адрес общего доступа методу setPermissionSet , а затем я могу вызвать listBlobs :

 $storageClient = new Microsoft_WindowsAzure_Storage_Blob('blob.core.windows.net', 'account name', ''); 
 $storageClient->setCredentials( 
     new Microsoft_WindowsAzure_Credentials_SharedAccessSignature() 
 );
 $storageClient->getCredentials()->setPermissionSet(array( $sharedAccessUrl ));
 $blobs = $storageClient->listBlobs("pics");
 foreach($blobs as $blob)
 {
     echo $blob->name."<br/>";
 }

Еще одна вещь, о которой следует упомянуть в приведенном выше коде: чтобы использовать URL-адрес общего доступа для установки разрешений, обратите внимание, что мне нужно было заранее знать имя учетной записи хранения. Эта информация не содержится в подписанном URL-адресе и создает проблемы, если вы не знаете учетную запись хранения, с которой связан подписанный URL-адрес.

Вот и все на сегодня. Если вы заинтересованы в том , как создаются общие сигнатуры доступа, я предлагаю смотреть на исходный код для createSignature метода на SharedAccessSignature класса в Windows Azure SDK. (Суть это…

$signature = base64_encode(hash_hmac('sha256', $stringToSign, $this->_accountKey, true));

… но создание строки для подписи немного сложно.)

Спасибо.