Kontrola dostępu w interfejsie API SQL usługi Azure Cosmos DB

Azure Cosmos DB to w pełni zarządzana usługa bazy danych NoSQL do tworzenia nowoczesnych aplikacji. W tym artykule omówiono interfejs API SQL dla usługi Azure Cosmos DB. Dostęp do zasobów w interfejsie API SQL jest zarządzany za pomocą tokenu klucza głównego lub tokenu zasobu. W celu uzyskania dostępu do zasobu wybrany token jest uwzględniany w nagłówku autoryzacji REST w ramach ciągu autoryzacji.

Tokeny klucza głównego

Token klucza głównego to cały token klucza dostępu, który umożliwia użytkownikom pełną kontrolę nad zasobami usługi Cosmos DB na określonym koncie. Klucz główny jest tworzony podczas tworzenia konta. Istnieją dwa zestawy kluczy głównych, klucz podstawowy i klucz pomocniczy. Administrator konta może następnie wykonywać rotację kluczy przy użyciu klucza pomocniczego. Ponadto administrator konta może również ponownie wygenerować klucze zgodnie z potrzebami. Aby uzyskać instrukcje dotyczące ponownego generowania i rolowania kluczy, zobacz Bezpieczny dostęp do danych w usłudze Azure Cosmos DB.

Tokeny zasobów

Tokeny zasobów są tworzone, gdy użytkownicy w bazie danych są skonfigurowani z uprawnieniami dostępu do precyzyjnej kontroli dostępu w zasobie, znanym również jako zasób uprawnień. Zasób uprawnień zawiera token zasobu skrótu skonstruowany z informacjami dotyczącymi ścieżki zasobu i typu dostępu, do których użytkownik ma dostęp. Token zasobu uprawnień jest powiązany z czasem, a okres ważności może zostać zastąpiony. Gdy zasób uprawnień jest uruchamiany w dniu (POST, GET, PUT), zostanie wygenerowany nowy token zasobu. Aby uzyskać informacje na temat uprawnień i tokenów zasobów, zobacz Operacje na uprawnieniach usługi Cosmos DB.

Nagłówek autoryzacji

Wszystkie operacje REST, niezależnie od tego, czy używasz tokenu klucza głównego, czy tokenu zasobu, muszą zawierać nagłówek autoryzacji z ciągiem autoryzacji w celu interakcji z zasobem. Ciąg autoryzacji ma następujący format:

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

Ciąg autoryzacji wygląda następująco:

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

Części ujęte w nawiasy są następujące:

Ciąg autoryzacji powinien zostać zakodowany przed dodaniem go do żądania REST, aby upewnić się, że nie zawiera on nieprawidłowych znaków. Upewnij się, że jest on zakodowany w formacie Base64 przy użyciu protokołu MIME RFC2045. Ponadto klucz główny używany w hashsignature powinien być dekodowany przy użyciu protokołu MIME RFC2045, ponieważ jest zakodowany w formacie Base64. Jeśli widzisz problemy z autoryzacją, zobacz, jak diagnozować i rozwiązywać problemy z nieautoryzowanymi wyjątkami.

Konstruowanie sygnatury skrótu tokenu dla tokenu głównego

Podpis skrótu dla tokenu klucza głównego można skonstruować z następujących parametrów: Verb, ResourceType, ResourceLink i Date.

  1. Czasownik reprezentuje czasownik HTTP żądania. Możliwe wartości to: get, post, put, patch, delete

Uwaga:: Wartości muszą być małe.

  1. Część ResourceType ciągu identyfikuje typ zasobu, dla którego jest wymagane żądanie. Możliwe wartości:
    • Operacje bazy danych: dbs
    • Operacje kontenera: colls
    • Procedury składowane: sprocs
    • Funkcje zdefiniowane przez użytkownika: udfs
    • Wyzwalaczy: triggers
    • Użytkowników: users
    • Uprawnienia: permissions
    • Operacje na poziomie elementu: docs

Uwaga: Wartości są uwzględniane w wielkości liter i muszą być małymi literami.

  1. Część resourceLink ciągu jest właściwością tożsamości zasobu, na który jest kierowane żądanie. Wartość ResourceLink jest zależna od operacji, którą próbujesz wykonać. Każda operacja będzie miała własny odpowiedni zasób ResourceLink zgodnie z tą konwencją:
    • Jeśli operacja jest wykonywana względem określonego zasobu, wartość jest linkiem do tego zasobu. Przykłady:

      • Aby uzyskać dostęp do bazy danych, użyj: dbs/{databaseId}
      • Aby uzyskać informacje o użyciu dokumentu: dbs/{databaseId}/colls/{containerId}/docs/{docId}
    • Jeśli operacja jest wykonywana względem zestawu zasobów (lista, tworzenie, zapytanie), wartość jest linkiem zasobu nadrzędnego. Przykłady:

      • Aby utworzyć dokument, użyj polecenia: dbs/{databaseId}/colls/{containerId}
      • Aby utworzyć procedurę składowaną, użyj: dbs/{databaseId}/colls/{containerId}
      • Aby utworzyć kontener, użyj: dbs/{databaseId}
      • W przypadku tworzenia bazy danych użyj: "" —> pusty ciąg, ponieważ bazy danych nie mają zasobu nadrzędnego

Uwaga: Nazwy zasobów, do których są przywoływane jako część wartości ResourceLink, są uwzględniane wielkość liter i muszą być zgodne z wielkością liter, w jaki zostały zadeklarowane w bazie danych. Inne składniki muszą mieć małe litery.

  1. Część Daty ciągu to data i godzina wysłania komunikatu (w formacie "DATA HTTP", zgodnie z definicją w formatach daty/godziny RFC 7231), na przykład "Wt, 01 listopada 1994 08:12:31 GMT".

    W języku C#można go uzyskać przy użyciu specyfikatora formatu "R" dla DateTime.UtcNow wartości.

    Ta sama data (w tym samym formacie) również musi zostać przekazana jako x-ms-date nagłówek w żądaniu.

Uwaga: Wartość jest uwzględniana w wielkości liter i musi zawierać małe litery.

Aby obliczyć podpis, użyjemy funkcji uwierzytelniania komunikatów opartej na skrótach (HMAC) opartej na skrótach SHA256 z kluczem usługi CosmosDB jako kluczem tajnym.

Ładunek funkcji skrótu jest oparty na 4 składnikach przedstawionych powyżej przy użyciu następującego formatu: "{verb}\n{resourceType}\n{resourceLink}\n{date}\n\n" (zwróć uwagę na dodatkowy nowy wiersz na końcu ładunku).

Wynik zakodowany w formacie Base64 funkcji będzie używany jako podpis podczas konstruowania nagłówka Autoryzacja dla wywołania.

Przykład [C#] dla prawidłowego nagłówka autoryzacji:

    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");

Przykładowa metoda [C#] umożliwiająca wygenerowanie prawidłowego podpisu autoryzacji:

Aby wyświetlić kompletne przykłady dla interfejsu API REST usługi Cosmos DB, odwiedź repozytorium Przykłady interfejsu API REST usługi Cosmos DB w usłudze 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;
}
  

Przykład [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);  
}  
  

Przykładowe kodowanie:

Argument Wartość
Czasownik GET
Typ zasobu "dbs"
Link do zasobu "dbs/ToDoList"
Date Czw, 27 Kwi 2017 00:51:12 GMT
Klucz dsZQi3KtZmCv1ljt3VNWN7sQUF1y5rJfC6kv5Jiwv
W0EndXdDku/dkKBp8/ufDToSxLzR4y+O/0H/t4bQtVNw==
Typ klucza master
Wersja tokenu 1.0
Ciąg autoryzacji wyjściowej type%3dmaster%26ver%3d1.0%26sig%3dc09PEVJr
gp2uQRkr934kFbTqhByc7TVr3OHyqlu%2bc%2bc%3d

Konstruowanie sygnatury skrótu dla tokenu zasobu

Tokeny zasobów muszą być generowane przez serwer pośredni. Serwer służy jako strażnik klucza głównego i generuje ograniczone czasowo tokeny dla niezaufanych klientów, takich jak przeglądarki internetowe.

Ten serwer wykonuje następujące kroki:

  1. Obsługuje przychodzące żądania klienta dla nowych tokenów.

  2. Weryfikuje tożsamość klienta w sposób specyficzny dla aplikacji.

  3. Jeśli klient pomyślnie uwierzytelnia się, używa interfejsów usługi Cosmos DB (sdk lub REST) do wygenerowania nowego tokenu ograniczonego czasowo i zwraca go do klienta.

Zobacz też