Управление доступом в API SQL Azure Cosmos DB

Azure Cosmos DB является полностью управляемой службой для баз данных NoSQL и предназначена для разработки современных приложений. В этой статье рассматривается API SQL для Azure Cosmos DB. Доступ к ресурсам в API SQL регулируется с использованием маркера главного ключа или маркера ресурса. Чтобы получить доступ к ресурсу, выбранный маркер включается в заголовок авторизации REST как часть строки авторизации.

Маркеры главного ключа

Маркер ключа master — это маркер ключа доступа, который позволяет пользователям иметь полный контроль над ресурсами Cosmos DB в определенной учетной записи. Главный ключ создается при создании учетной записи. Существует два набора главных ключей: первичный ключ и вторичный ключ. Администратор учетной записи может сменить ключи с помощью вторичного ключа. Кроме того, при необходимости администратор учетной записи также может повторно создавать ключи. Инструкции по повторному созданию и смене ключей см. в статье Безопасный доступ к данным в Azure Cosmos DB.

Маркеры ресурсов

Маркеры ресурсов создаются, когда пользователи в базе данных настраиваются с разрешениями на доступ для точного управления доступом к ресурсу, также известному как ресурс разрешений. Ресурс разрешений содержит маркер хэш-ресурса, созданный со сведениями о пути к ресурсу и типе доступа, к которому имеет доступ пользователь. Маркер ресурса разрешения имеет ограниченный срок действия, который может быть переопределен. При обработке ресурса разрешения (с помощью запросов POST, GET, PUT) создается новый маркер ресурса. Сведения о разрешениях и маркерах ресурсов см. в разделе Операции с разрешениями Cosmos DB.

Заголовок авторизации

Все операции REST, независимо от того, используете ли вы маркер ключа master или маркер ресурса, должны включать заголовок авторизации со строкой авторизации для взаимодействия с ресурсом. Строка авторизации имеет следующий формат:

type={typeoftoken}&ver={tokenversion}&sig={hashsignature}  

Строка авторизации выглядит следующим образом:

type=master&ver=1.0&sig=5mDuQBYA0kb70WDJoTUzSBMTG3owkC0/cEN4fqa18/s=  

В квадратные скобки заключены следующие элементы:

  • {typeoftoken} обозначает тип токена: master, ресурс или aad (если вы используете Azure Cosmos DB RBAC).

  • {tokenversion} обозначает версию маркера, в настоящее время — 1.0.

  • {hashsignature} обозначает хэшированную подпись маркера или маркер oauth , если вы используете RBAC Azure Cosmos DB.

Прежде чем добавить строку авторизации в запрос REST, ее нужно закодировать, чтобы убедиться, что она не содержит недопустимых символов. Убедитесь, что он закодирован в Кодировке Base64 с помощью MIME RFC2045. Кроме того, ключ master, используемый в хэш-знаке, следует декодировать с помощью MIME RFC2045, так как он имеет кодировку Base64. Если вы видите какие-либо проблемы с авторизацией, ознакомьтесь с диагностикой и устранением несанкционированных исключений.

Создание хэшированных подписей маркера для маркера master

Хэш-подпись для маркера ключа master можно создать на основе следующих параметров: Verb, ResourceType, ResourceLink и Date.

  1. Команда представляет HTTP-команду запроса. Возможные значения: get, post, put, patch, delete

Примечание. Значения должны быть строчными.

  1. Часть ResourceType строки определяет тип ресурса, для котором выполняется запрос. Возможны следующие значения:
    • Операции с базой данных: dbs
    • Операции с контейнерами. colls
    • Хранимые процедуры: sprocs
    • Определяемые пользователем функции. udfs
    • Триггеры: triggers
    • Пользователей: users
    • Разрешения: permissions
    • Операции на уровне элементов: docs

Примечание: Значения чувствительны к регистру и должны быть строчными.

  1. Часть Строки ResourceLink является свойством identity ресурса, на который направлен запрос. Значение ResourceLink зависит от операции, выполняемой вами. Каждая операция будет иметь собственный соответствующий Объект ResourceLink в соответствии с этим соглашением:
    • Если операция выполняется с определенным ресурсом, значением является ссылка на этот ресурс. Примеры:

      • Для получения использования базы данных: dbs/{databaseId}
      • Для получения документа: dbs/{databaseId}/colls/{containerId}/docs/{docId}
    • Если операция выполняется с набором ресурсов (List, Create, Query), то значением является ссылка родительского ресурса. Примеры:

      • Для использования создания документа: dbs/{databaseId}/colls/{containerId}
      • Для создания хранимой процедуры используйте: dbs/{databaseId}/colls/{containerId}
      • Для создания контейнера используйте: dbs/{databaseId}
      • Для создания базы данных используйте : "" —> пустая строка, так как базы данных не имеют родительского ресурса.

Примечание: Имена ресурсов, на которые ссылаются как часть значения ResourceLink, чувствительны к регистру и должны соответствовать регистру того, как они были объявлены в базе данных. Остальные компоненты должны быть строчными.

  1. Часть даты строки — это дата и время отправки сообщения в формате UTC (в формате "HTTP-date", как определено в форматах даты и времени RFC 7231), например "Вт, 01 ноября 1994 г. 08:12:31 GMT".

    В C# его можно получить с помощью описателя формата "R" в значении DateTime.UtcNow .

    Эту же дату (в том же формате) также необходимо передать в качестве x-ms-date заголовка в запросе.

Примечание: Значение учитывает регистр и должно быть все строчными буквами.

Для вычисления сигнатуры используется функция HMAC на основе хэша на основе SHA256 с ключом CosmosDB в качестве секрета.

Полезные данные для функции хэширования основаны на 4 представленных выше компонентах в следующем формате: "{verb}\n{resourceType}\n{resourceLink}\n{date}\n\n" (обратите внимание на дополнительную новую строку в конце полезных данных).

Результат функции в кодировке Base64 будет использоваться в качестве сигнатуры при создании заголовка Authorization для вызова .

Пример [C#] для допустимого заголовка авторизации:

    httpClient.DefaultRequestHeaders.Clear();
    httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
    httpClient.DefaultRequestHeaders.Add("authorization", auth); //generated using method below
    httpClient.DefaultRequestHeaders.Add("x-ms-date", requestDateString);
    httpClient.DefaultRequestHeaders.Add("x-ms-version", "2018-12-31");

Пример метода [C#] для создания допустимой подписи авторизации:

Полные примеры для REST API Cosmos DB см. в репозитории примеров REST API Cosmos DB на сайте GitHub.

  
string GenerateMasterKeyAuthorizationSignature(HttpMethod verb, ResourceType resourceType, string resourceLink, string date, string key)
{
    var keyType = "master";
    var tokenVersion = "1.0";
    var payload = $"{verb.ToString().ToLowerInvariant()}\n{resourceType.ToString().ToLowerInvariant()}\n{resourceLink}\n{date.ToLowerInvariant()}\n\n";

    var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) };
    var hashPayload = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payload));
    var signature = Convert.ToBase64String(hashPayload);
    var authSet = WebUtility.UrlEncode($"type={keyType}&ver={tokenVersion}&sig={signature}");

    return authSet;
}
  

Пример [Node.js]:

  
var crypto = require("crypto");  
  
function getAuthorizationTokenUsingMasterKey(verb, resourceType, resourceId, date, masterKey) {  
    var key = new Buffer(masterKey, "base64");  
  
    var text = (verb || "").toLowerCase() + "\n" +   
               (resourceType || "").toLowerCase() + "\n" +   
               (resourceId || "") + "\n" +   
               date.toLowerCase() + "\n" +   
               "" + "\n";  
  
    var body = new Buffer(text, "utf8");  
    var signature = crypto.createHmac("sha256", key).update(body).digest("base64");  
  
    var MasterToken = "master";  
  
    var TokenVersion = "1.0";  
  
    return encodeURIComponent("type=" + MasterToken + "&ver=" + TokenVersion + "&sig=" + signature);  
}  
  

Пример кодирования:

Аргумент Значение
Команда GET
Тип ресурса "dbs"
Ссылка на ресурс "dbs/ToDoList"
Дата Чт, 27 Апреля 2017 00:51:12 GMT
Ключ dsZQi3KtZmCv1ljt3VNWNm7sQUF1y5rJfC6kv5Jiwv
W0EndXdDku/dkKBp8/ufDToSxLzR4y+O/0H/t4bQtVNw==
Тип ключа master
Версия маркера 1,0
Строка авторизации выходных данных type%3dmaster%26ver%3d1.0%26sig%3dc09PEVJr
gp2uQRkr934kFbTqhByc7TVr3OHyqlu%2bc%2bc%3d

Создание хэш-подписи для маркера ресурса

Маркеры ресурсов должны создаваться промежуточным сервером. Сервер выступает в качестве защитника ключа master и создает маркеры с ограниченным временем для ненадежных клиентов, таких как веб-браузеры.

Этот сервер выполняет следующие действия:

  1. Обрабатывает входящие клиентские запросы для новых маркеров.

  2. Проверяет удостоверение клиента способом, зависящим от приложения.

  3. Если клиент успешно проходит проверку подлинности, он использует интерфейсы Cosmos DB (ПАКЕТ SDK или REST) для создания нового ограниченного по времени маркера и возвращает его клиенту.

См. также: