Авторизация с помощью общего ключа
Каждый запрос, сделанный к службе хранилища, должен быть авторизован, если только запрос не предназначен для большого двоичного объекта или ресурса контейнера, который был предоставлен для общедоступного или подписанного доступа. Одним из вариантов авторизации запроса является использование общего ключа, описанного в этой статье.
Важно!
Для оптимальной безопасности корпорация Майкрософт рекомендует по возможности использовать Microsoft Entra ID с управляемыми удостоверениями для авторизации запросов к blob-объектам, очередям и табличным данным. Авторизация с помощью Microsoft Entra ID и управляемых удостоверений обеспечивает превосходную безопасность и простоту использования по сравнению с авторизацией с помощью общего ключа. Дополнительные сведения см. в статье Авторизация с помощью Microsoft Entra ID. Дополнительные сведения об управляемых удостоверениях см. в статье Что такое управляемые удостоверения для ресурсов Azure.
Для ресурсов, размещенных за пределами Azure, например локальных приложений, можно использовать управляемые удостоверения через Azure Arc. Например, приложения, работающие на серверах с поддержкой Azure Arc, могут использовать управляемые удостоверения для подключения к службам Azure. Дополнительные сведения см. в статье Проверка подлинности в ресурсах Azure на серверах с поддержкой Azure Arc.
Для сценариев, в которых используются подписанные URL-адреса (SAS), корпорация Майкрософт рекомендует использовать SAS делегирования пользователей. SAS делегирования пользователей защищен с помощью Microsoft Entra учетных данных вместо ключа учетной записи. Дополнительные сведения о подписанных URL-адресах см. в статье Create SAS делегирования пользователей.
Службы BLOB-объектов, очередей, таблиц и файлов поддерживают следующие схемы авторизации общих ключей для версии 2009-09-19 и более поздних версий (для службы BLOB-объектов, очередей и таблиц) и версии 2014-02-14 и более поздних версий (для службы файлов):
Shared Key для служб BLOB-объектов, очередей и файлов. Используйте схему авторизации с общим ключом для выполнения запросов к службам BLOB-объектов, очередей и файлов. Авторизация с общим ключом в версии 2009-09-19 и более поздних поддерживает дополненную строку подписи для повышения безопасности и требует обновления службы для авторизации с помощью этой дополненной подписи.
Shared Key для службы таблиц. Используйте схему авторизации с общим ключом для выполнения запросов к службе таблиц с помощью REST API. Авторизация с общим ключом для службы таблиц в версии 2009-09-19 и более поздних использует ту же строку подписи, что и в предыдущих версиях службы таблиц.
Shared Key Lite. Используйте схему авторизации Lite с общим ключом для выполнения запросов к службам BLOB-объектов, очередей, таблиц и файлов.
В версиях 2009-09-19 и более поздних версий служб BLOB-объектов и очередей авторизация с общим ключом поддерживает использование строки подписи, идентичной той, которая поддерживалась для общих ключей в предыдущих версиях служб BLOB-объектов и очередей. Поэтому можно использовать Shared Key Lite для запросов к службам больших двоичных объектов и очередей без обновления строки подписи.
Для авторизованного запроса требуется два заголовка Date
: или x-ms-date
и заголовок Authorization
. Следующие шаги описывают процесс создания этих заголовков.
Важно!
Служба хранилища Azure поддерживает как HTTP, так и HTTPS, но настоятельно рекомендуется использовать HTTPS.
Примечание
Контейнер или большой двоичный объект можно сделать доступным для общего доступа, задав разрешения контейнера. Дополнительные сведения см. в статье Управление доступом к ресурсам службы хранилища Azure. Контейнер, большой двоичный объект, очередь или таблица могут быть доступны для подписанного доступа с помощью подписанного URL-адреса; подписанный URL-адрес авторизоваться с помощью другого механизма. Дополнительные сведения см. в разделе Делегирование доступа с помощью подписанного URL-адреса .
Указание заголовка Date
Все авторизованные запросы должны включать метку времени utc для запроса. Указывать отметку времени можно либо в заголовке x-ms-date
, либо в стандартном заголовке HTTP/HTTPS Date
. Если в запросе указаны оба заголовка, то значение x-ms-date
используется как время создания запроса.
Службы хранилища обеспечивают, чтобы запрос был не старее 15 минут на момент достижения им службы. Это дает защиту от некоторых атак на систему безопасности, включая атаки воспроизведения. Если эта проверка завершается ошибкой, сервер возвращает код ответа 403 (отклонено).
Примечание
Заголовок x-ms-date
предоставляется потому, что некоторые клиентские библиотеки HTTP и прокси-серверы автоматически задают Date
заголовок и не дают разработчику возможности прочитать его значение, чтобы включить его в авторизованный запрос. Задавая x-ms-date
, следует создать подпись с пустым значением для заголовка Date
.
Указание заголовка авторизации
Авторизованный запрос должен содержать заголовок Authorization
. Если этот заголовок не включен, запрос является анонимным и выполняется успешно только для контейнера или большого двоичного объекта, помеченного для общего доступа, или контейнера, большого двоичного объекта, очереди или таблицы, для которых была предоставлена подпись общего доступа для делегированного доступа.
Чтобы авторизовать запрос, необходимо подписать запрос ключом учетной записи, которая выполняет запрос, и передать эту подпись в составе запроса.
Формат заголовка Authorization
выглядит следующим образом:
Authorization="[SharedKey|SharedKeyLite] <AccountName>:<Signature>"
где SharedKey
или SharedKeyLite
— название схемы авторизации, AccountName
— имя учетной записи, запрашивающей ресурс, а Signature
— код проверки подлинности на основе хэша (HMAC), построенный из запроса и вычисленный с помощью алгоритма SHA256, а затем закодированный в Base64.
Примечание
Можно запросить ресурс, который находится в другой учетной записи, если к этому ресурсу имеется общий доступ.
Следующие шаги описывают процесс создания заголовка Authorization
.
Создание строки подписи
Способ создания строки подписи зависит от того, для какой службы и версии вы авторизуете и какую схему авторизации вы используете. При создании строки подписи помните о следующем.
Часть VERB строки — это HTTP-команда, например GET или PUT, и она должна быть написана прописными буквами.
Для авторизации общего ключа для служб BLOB-объектов, очередей и файлов каждый заголовок, включенный в строку подписи, может отображаться только один раз. Если какой-либо заголовок дублирован, то служба возвращает код состояния 400 (неправильный запрос).
Значения всех стандартных заголовков HTTP необходимо включить в строку в порядке, показанном в формате подписи, без имен заголовков. Эти заголовки могут быть пустыми, если они не указаны в рамках запроса; в этом случае требуется только символ новой строки.
x-ms-date
Если заголовок указан, заголовок можно игнорироватьDate
, независимо от того, указан ли он в запросе, и просто указать пустую строку дляDate
части строки подписи. В этом случае следуйте инструкциям в разделе Создание канонической строки заголовков , чтобы добавить заголовокx-ms-date
.Допустимо указать и
x-ms-date
;Date
в этом случае служба использует значениеx-ms-date
.Если заголовок
x-ms-date
не указан, укажите заголовокDate
в строке подписи без включения имени заголовка.Все показанные символы новой строки (\n) необходимы в строке подписи.
Строка подписи содержит канонические заголовки и строки ресурсов. Канонизация этих строк преобразовывает их в стандартный формат, распознаваемый службой хранилища Azure. Подробные сведения о создании строк
CanonicalizedHeaders
иCanonicalizedResource
, которые являются частью строки подписи, см. в соответствующих подразделах ниже.
Службы BLOB-объектов, очередей и файлов (авторизация с общим ключом)
Для кодирования строки подписи Shared Key для запроса к версии 2009-09-19 или более поздней версии службы BLOB-объектов или очередей, а также версии 2014-02-14 или более поздней версии службы файлов используйте следующий формат:
StringToSign = VERB + "\n" +
Content-Encoding + "\n" +
Content-Language + "\n" +
Content-Length + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
If-Modified-Since + "\n" +
If-Match + "\n" +
If-None-Match + "\n" +
If-Unmodified-Since + "\n" +
Range + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;
Важно!
В текущей версии поле Content-Length должно быть пустой строкой, если длина содержимого запроса равна нулю. В версии 2014-02-14 и более ранних версиях длина содержимого включалась, даже если она была нулевой. Дополнительные сведения о старом поведении см. ниже.
В следующем примере показана строка сигнатуры для операции получения BLOB-объекта . Если значение заголовка отсутствует, указывается только символ новой строки.
GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Fri, 26 Jun 2015 23:39:12 GMT\nx-ms-version:2015-02-21\n/myaccount/mycontainer\ncomp:metadata\nrestype:container\ntimeout:20
В построчном разборе показана каждая часть одной и той же строки:
GET\n /*HTTP Verb*/
\n /*Content-Encoding*/
\n /*Content-Language*/
\n /*Content-Length (empty string when zero)*/
\n /*Content-MD5*/
\n /*Content-Type*/
\n /*Date*/
\n /*If-Modified-Since */
\n /*If-Match*/
\n /*If-None-Match*/
\n /*If-Unmodified-Since*/
\n /*Range*/
x-ms-date:Fri, 26 Jun 2015 23:39:12 GMT\nx-ms-version:2015-02-21\n /*CanonicalizedHeaders*/
/myaccount /mycontainer\ncomp:metadata\nrestype:container\ntimeout:20 /*CanonicalizedResource*/
Затем следует закодировать эту строку, применив алгоритм HMAC-SHA256 к закодированной в UTF-8 строке подписи, создать заголовок Authorization
и добавить этот заголовок к запросу. В следующем примере показан заголовок Authorization
для той же операции:
Authorization: SharedKey myaccount:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=
Чтобы использовать авторизацию с общим ключом с версией 2009-09-19 и более поздними версиями служб BLOB-объектов и очередей, необходимо обновить код для использования этой дополненной строки подписи.
Если вы предпочитаете перенести код на 2009-09-19 или более позднюю версию служб BLOB-объектов и очередей с наименьшими возможными изменениями, вы можете изменить существующие Authorization
заголовки, чтобы использовать общий ключ Lite вместо общего ключа. Формат подписи, необходимый для Shared Key Lite, идентичен тому, что необходим для Shared Key в версиях служб больших двоичных объектов и очередей до 2009-09-19.
Важно!
При выполнении доступа к дополнительному расположению в учетной записи хранения, для которого включена георепликация доступа для чтения (RA-GRS), не включайте обозначение -secondary
в заголовок авторизации. Для проверки подлинности имя учетной записи всегда является именем первичного расположения, даже для вторичного доступа.
Заголовок Content-Length в версии 2014-02-14 и более ранних версиях
При использовании версии 2014-02-14 или более ранней, если Content-Length
значение равно нулю, задайте для Content-Length
части StringToSign
0
значение . Обычно это пустая строка.
Например, для следующего запроса значение заголовка Content-Length
включается в StringToSign
, даже если оно равно нулю.
PUT http://myaccount/mycontainer?restype=container&timeout=30 HTTP/1.1
x-ms-version: 2014-02-14
x-ms-date: Fri, 26 Jun 2015 23:39:12 GMT
Authorization: SharedKey myaccount:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=
Content-Length: 0
Создается StringToSign
следующим образом:
Version 2014-02-14 and earlier:
PUT\n\n\n\n0\n\n\n\n\n\n\n\nx-ms-date:Fri, 26 Jun 2015 23:39:12 GMT\nx-ms-version:2014-02-14\n/myaccount/mycontainer\nrestype:container\ntimeout:30
В то время как в версиях после 2014-02-14 должен StringToSign
содержать пустую строку для Content-Length
:
Version 2015-02-21 and later:
PUT\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Fri, 26 Jun 2015 23:39:12 GMT\nx-ms-version:2015-02-21\n/myaccount/mycontainer\nrestype:container\ntimeout:30
Служба таблиц (авторизация с общим ключом)
Для авторизации запроса, сделанного к службе таблиц, необходимо использовать авторизацию общего ключа, если служба использует REST API для выполнения запроса. Формат строки подписи для Shared Key при запросе к службе таблиц тот же, что для всех версий.
Строка подписи общего ключа для запроса к службе таблиц немного отличается от строки запроса к службе BLOB-объектов или очередей, так как она не включает CanonicalizedHeaders
часть строки. Кроме того, заголовок Date
в этом случае никогда не пустует, даже если в запросе задан заголовок x-ms-date
. Если в запросе задан заголовок x-ms-date
, это значение также используется для значения заголовка Date
.
Для кодирования строки подписи для запроса к службе таблиц, сделанного с помощью API-интерфейса REST, используйте следующий формат:
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedResource;
Примечание
Начиная с версии 2009-09-19, служба таблиц требует, чтобы все вызовы REST включали заголовки DataServiceVersion
и MaxDataServiceVersion
. Дополнительные сведения см. в разделе Настройка заголовков версий службы данных OData .
Службы BLOB-объектов, очередей и файлов (авторизация с общим ключом Lite)
Вы можете использовать авторизацию Lite с общим ключом для авторизации запроса, сделанного в службах BLOB-объектов и очередей версии 2009-09-19 и более поздних версий, а также файловых служб 2014-02-14 и более поздних версий.
Строка подписи для Shared Key Lite идентична строке подписи, необходимой для авторизации с помощью общего ключа в версиях служб BLOB-объектов и очередей до 19.09.2009. Поэтому если вы хотите перенести код с наименьшим числом изменений в версии 2009-09-19 служб BLOB-объектов и очередей, можно изменить код, чтобы использовать общий ключ Lite, не изменяя саму строку подписи. Используя общий ключ Lite, вы не получите расширенные функции безопасности, предоставляемые с помощью общего ключа с версией 2009-09-19 и более поздних версий.
Для кодирования строки подписи для запроса к службе BLOB-объектов или очередей используйте следующий формат:
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;
В следующем примере показана строка подписи для операции Put BLOB-объекта . Обратите внимание, что строка заголовка Content-MD5 пуста. Заголовки, показанные в строке, — это пары "имя-значение", указывающие пользовательские значения метаданных для нового большого двоичного объекта.
PUT\n\ntext/plain; charset=UTF-8\n\nx-ms-date:Sun, 20 Sep 2009 20:36:40 GMT\nx-ms-meta-m1:v1\nx-ms-meta-m2:v2\n/testaccount1/mycontainer/hello.txt
Затем следует закодировать эту строку, применив алгоритм HMAC-SHA256 к закодированной в UTF-8 строке подписи, создать заголовок Authorization
и добавить этот заголовок к запросу. В следующем примере показан заголовок Authorization
для той же операции:
Authorization: SharedKeyLite myaccount:ctzMq410TV3wS7upTBcunJTDLEJwMAZuFPfr0mrrA08=
Служба таблиц (авторизация Lite с общим ключом)
Вы можете использовать авторизацию Lite с общим ключом, чтобы авторизовать запрос к любой версии службы таблиц.
Для кодирования строки подписи для запроса к службе таблиц, сделанного с помощью Shared Key Lite, используйте следующий формат:
StringToSign = Date + "\n"
CanonicalizedResource
В следующем примере показана строка подписи для операции Create Table.
Sun, 11 Oct 2009 19:52:39 GMT\n/testaccount1/Tables
Затем закодируйте эту строку с помощью алгоритма HMAC-SHA256, создайте заголовок Authorization
и добавьте заголовок к запросу. В следующем примере показан заголовок Authorization
для той же операции:
Authorization: SharedKeyLite testaccount1:uay+rilMVayH/SVI8X+a3fL8k/NxCnIePdyZSkqvydM=
Создание строки канонических заголовков
Чтобы построить часть CanonicalizedHeaders
строки подписи, выполните следующие действия.
Получите все заголовки для ресурса, начинающиеся с
x-ms-
, включая заголовокx-ms-date
.Преобразуйте все имена заголовков HTTP к нижнему регистру.
Лексикографически отсортируйте заголовки по имени в порядке возрастания. Каждый заголовок может отображаться в строке только один раз.
Примечание
Лексикографическое упорядочение не всегда может совпадать с обычным алфавитным порядком.
Замените все линейные пробелы в значении заголовка одним пробелом.
Линейные пробелы включают возврат каретки или ввод строки (CRLF), пробелы и табуляции. Дополнительные сведения см. в документе RFC 2616, раздел 4.2 . Не заменяйте пробелы внутри строки в кавычках.
Обрезка всех пробелов вокруг двоеточия в заголовке.
Наконец, добавьте символ новой строки к каждому каноническому заголовку в полученном списке. Постройте строку
CanonicalizedHeaders
, объединив все заголовки в этом списке в одну строку.
На приведенном ниже рисунке показан пример строки канонических заголовков.
x-ms-date:Sat, 21 Feb 2015 00:48:38 GMT\nx-ms-version:2014-02-14\n
Примечание
До версии службы 2016-05-31 заголовки с пустыми значениями были опущены в строке подписи. Теперь они представлены в CanonicalizedHeaders сразу после двоеточия с завершающей новой строкой.
Создание канонической строки ресурса
Часть строки подписи CanonicalizedResource
представляет ресурс служб хранилища, которому направлен запрос. Любая часть строки CanonicalizedResource
, выведенная из URI ресурса, должна быть кодирована точно так же, как в URI.
Для строки CanonicalizedResource
поддерживаются два формата.
Формат, поддерживающий авторизацию по общему ключу для служб BLOB-объектов и очередей версии 2009-09-19 и более поздних версий, а также для службы файлов 2014-02-14 и более поздних версий.
Формат, который поддерживает Shared Key и Shared Key Lite для всех версий службы таблиц, а также Shared Key Lite для версии 2009-09-19 и более поздних версий служб больших двоичных объектов и очередей. Этот формат идентичен тому, что использовался в предыдущих версиях служб хранилища.
Справку по созданию URI для ресурса, к которому производится доступ, см. в одном из следующих разделов:
Служба BLOB-объектов: именование и ссылки на контейнеры, большие двоичные объекты и метаданные
Служба очередей: адресация ресурсов службы очередей
Служба таблиц: адресация ресурсов службы таблиц
Файловая служба: именование общих папок, каталогов, файлов и метаданных и ссылки на нее
Важно!
Если ваша учетная запись хранения реплицируются при использовании георепликации с доступом только для чтения (RA-GRS) и выполняется доступ к ресурсу в дополнительном расположении, не включайте обозначение –secondary
в строку CanonicalizedResource
. URI ресурса, используемый в URI строки CanonicalizedResource
, должен быть URI ресурса из основного расположения.
Примечание
При авторизации в эмуляторе хранения имя учетной записи будет дважды отображаться в строке CanonicalizedResource
. Это ожидаемое поведение. При авторизации в службах хранилища Azure имя учетной записи будет отображаться в строке CanonicalizedResource
только один раз.
Формат общего ключа для 19.09.2009 и более поздних версий
Этот формат поддерживает авторизацию с общим ключом для версии 2009-09-19 и более поздних версий служб BLOB-объектов и очередей, а также для файловых служб 2014-02-14 и более поздних версий. Постройте строку CanonicalizedResource
в этом формате следующим образом.
Начиная с пустой строки (""), добавьте косую черту (/), а за ней имя учетной записи, владеющей ресурсом, к которому производится доступ.
Добавьте закодированный URI путь к ресурсу без параметров запроса.
Получите все параметры запроса для URI источника, включая параметр
comp
, если он существует.Преобразуйте все имена параметров к нижнему регистру.
Лексикографически отсортируйте параметры запроса по имени параметра по возрастанию.
Закодируйте в URL имя параметра и значение для каждого запроса.
Добавьте символ новой строки (\n) перед каждой парой имя-значение.
Добавьте имя и значение каждого параметра запроса к строке в следующем формате, включая двоеточие (:) между именем и значением.
parameter-name:parameter-value
Если параметр запроса имеет более одного значения, отсортируйте все значения лексикографически, а затем включите их в список с разделителями-запятыми:
parameter-name:parameter-value-1,parameter-value-2,parameter-value-n
Учитывайте следующие правила для создания канонической строки ресурса.
Избегайте использования символа новой строки (\ n) в значениях параметров запроса. Если его необходимо использовать, убедитесь, что он не влияет на канонический формат строки ресурса.
Не используйте запятые в значениях параметра запроса.
Ниже приведены некоторые примеры, в которых показана CanonicalizedResource
часть строки подписи, так как она может быть создана на основе заданного URI запроса:
Get Container Metadata
GET http://myaccount.blob.core.windows.net/mycontainer?restype=container&comp=metadata
CanonicalizedResource:
/myaccount/mycontainer\ncomp:metadata\nrestype:container
List Blobs operation:
GET http://myaccount.blob.core.windows.net/container?restype=container&comp=list&include=snapshots&include=metadata&include=uncommittedblobs
CanonicalizedResource:
/myaccount/mycontainer\ncomp:list\ninclude:metadata,snapshots,uncommittedblobs\nrestype:container
Get Blob operation against a resource in the secondary location:
GET https://myaccount-secondary.blob.core.windows.net/mycontainer/myblob
CanonicalizedResource:
/myaccount/mycontainer/myblob
Формат службы shared Key Lite и table для версии 19.09.2009 и более поздних версий
Этот формат поддерживает Shared Key и Shared Key Lite для всех версий службы таблиц, Shared Key Lite для версии 2009-09-19 и более поздних версий служб BLOB-объектов и очередей, а также для версии 2014-02-14 и более поздних версий службы файлов. Этот формат идентичен тому, что использовался в предыдущих версиях служб хранилища. Постройте строку CanonicalizedResource
в этом формате следующим образом.
Начиная с пустой строки (""), добавьте косую черту (/), а за ней имя учетной записи, владеющей ресурсом, к которому производится доступ.
Добавьте закодированный путь URI ресурса. Если в запросе URI обращается к компоненту ресурса, добавьте соответствующую строку в запрос. Строка запроса должна содержать знак вопроса и параметр
comp
(например,?comp=metadata
). Никакие другие параметры не должны быть включены в строку запроса.
Кодирование сигнатуры
Для кодирования сигнатуры вызовите алгоритм HMAC-SHA256 для строки сигнатуры в кодировке UTF-8 и закодируйте результат в Base64. Обратите внимание, что также необходимо декодировать ключ учетной записи хранения в Формате Base64. Используйте следующий формат (показан как псевдокод):
Signature=Base64(HMAC-SHA256(UTF8(StringToSign), Base64.decode(<your_azure_storage_account_shared_key>)))