Åtkomstkontroll i Azure Cosmos DB SQL API

Azure Cosmos DB är en fullständigt hanterad NoSQL-databastjänst för modern apputveckling. Den här artikeln beskriver SQL-API:et för Azure Cosmos DB. Åtkomst till resurser i SQL-API:et styrs av en huvudnyckeltoken eller en resurstoken. För att få åtkomst till en resurs ingår den valda token i REST-auktoriseringsrubriken, som en del av auktoriseringssträngen.

Huvudnyckeltoken

Huvudnyckeltoken är token för alla åtkomstnycklar som gör att användarna kan ha fullständig kontroll över Cosmos DB-resurser i ett visst konto. Huvudnyckeln skapas när ett konto skapas. Det finns två uppsättningar huvudnycklar, primärnyckeln och den sekundära nyckeln. Administratören för kontot kan sedan använda nyckelrotation med hjälp av den sekundära nyckeln. Dessutom kan kontoadministratören återskapa nycklarna efter behov. Anvisningar om hur du återskapar och rullar nycklar finns i Säker åtkomst till data i Azure Cosmos DB.

Resurstoken

Resurstoken skapas när användare i en databas konfigureras med åtkomstbehörigheter för exakt åtkomstkontroll på en resurs, även kallat en behörighetsresurs. En behörighetsresurs innehåller en hash-resurstoken som skapats med information om resurssökvägen och åtkomsttypen som en användare har åtkomst till. Behörighetsresurstoken är tidsbunden och giltighetsperioden kan åsidosättas. När en behörighetsresurs åtgärdas (POST, GET, PUT) genereras en ny resurstoken. Information om behörigheter och resurstoken finns i Åtgärder för Cosmos DB-behörigheter.

Auktoriseringshuvud

Alla REST-åtgärder, oavsett om du använder en huvudnyckeltoken eller resurstoken, måste inkludera auktoriseringshuvudet med auktoriseringssträngen för att kunna interagera med en resurs. Auktoriseringssträngen har följande format:

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

En auktoriseringssträng ser ut så här:

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

Delarna inom hakparenteser är följande:

  • {typeoftoken} anger typen av token: master, resurs eller aad (om du använder Azure Cosmos DB RBAC).

  • {tokenversion} anger versionen av token, för närvarande 1.0.

  • {hashsignature} anger den hashade tokensignaturen eller oauth-token om du använder Azure Cosmos DB RBAC.

Auktoriseringssträngen bör kodas innan den läggs till i REST-begäran för att säkerställa att den inte innehåller några ogiltiga tecken. Kontrollera att den är Base64-kodad med MIME RFC2045. Dessutom bör huvudnyckeln som används i hashsignature avkodas med MIME RFC2045 eftersom den är Base64-kodad. Om du ser några problem med auktorisering kan du läsa om hur du diagnostiserar och felsöker obehöriga undantag.

Skapa den hashade tokensignaturen för en huvudtoken

Hash-signaturen för huvudnyckeltoken kan konstrueras från följande parametrar: Verb, ResourceType, ResourceLink och Datum.

  1. Verbet representerar HTTP-verbet för din begäran. Möjliga värden är: get, post, put, patch, delete

Obs! Värdena måste vara gemener.

  1. ResourceType-delen av strängen identifierar den typ av resurs som begäran gäller för. Möjliga värden:
    • Databasåtgärder: dbs
    • Containeråtgärder: colls
    • Lagrade procedurer: sprocs
    • Användardefinierade funktioner: udfs
    • Utlösare: triggers
    • Användare: users
    • Behörigheter: permissions
    • Åtgärder på objektnivå: docs

Observera: Värdena är skiftlägeskänsliga och måste vara gemener.

  1. ResourceLink-delen av strängen är identitetsegenskapen för resursen som begäran riktas mot. ResourceLink-värdet är beroende av den åtgärd som du försöker köra. Varje åtgärd har en egen motsvarande ResourceLink enligt den här konventionen:
    • Om åtgärden utförs mot en specifik resurs är värdet länken till den resursen. Exempel:

      • För Att hämta databasanvändning: dbs/{databaseId}
      • För Att hämta dokumentanvändning: dbs/{databaseId}/colls/{containerId}/docs/{docId}
    • Om åtgärden utförs mot en uppsättning resurser (Lista, Skapa, Fråga) är värdet länken för den överordnade resursen. Exempel:

      • För användning av skapa dokument: dbs/{databaseId}/colls/{containerId}
      • Använd för att skapa lagrad procedur: dbs/{databaseId}/colls/{containerId}
      • För Att skapa en container använder du: dbs/{databaseId}
      • För Skapa databas använder du: "" –> en tom sträng eftersom databaser inte har någon överordnad resurs

Observera: Resursnamnen som refereras som en del av ResourceLink-värdet är skiftlägeskänsliga och måste matcha höljet för hur de deklarerades i databasen. De andra komponenterna måste vara gemener.

  1. Datumdelen av strängen är UTC-datum och tid då meddelandet skickades (i formatet "HTTP-date" enligt definitionen i RFC 7231 Datum/tid-format), till exempel "Tis, 01 nov 1994 08:12:31 GMT".

    I C# kan den hämtas med hjälp av R-formatspecificeraren för DateTime.UtcNow värdet.

    Samma datum (i samma format) måste också skickas som x-ms-date rubrik i begäran.

Observera: Värdet är skiftlägeskänsligt och måste vara gemener.

För att beräkna signaturen använder vi funktionen SHA256-baserad hashbaserad kod för meddelandeautentisering (HMAC) med CosmosDB-nyckeln som hemlighet.

Nyttolasten för hashfunktionen baseras på de 4 komponenter som presenteras ovan med följande format: "{verb}\n{resourceType}\n{resourceLink}\n{date}\n\n" (observera den extra nya raden i slutet av nyttolasten).

Det Base64-kodade resultatet av funktionen används som signatur när du skapar auktoriseringshuvudet för anropet.

Exempel [C#] för ett giltigt auktoriseringshuvud:

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

Exempel på [C#]-metod för att generera en giltig auktoriseringssignatur:

Om du vill se fullständiga exempel för Cosmos DB REST API går du till Cosmos DB REST API Samples-lagringsplatsen på 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;
}
  

Exempel [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);  
}  
  

Exempelkodning:

Argument Värde
Verb GET
Resurstyp "dbs"
Resurslänk "dbs/ToDoList"
Date Tor, 27 apr 2017 00:51:12 GMT
Nyckel dsZQi3KtZmCv1ljt3VNWNm7sQUF1y5rJfC6kv5Jiwv
W0EndXdDku/dkKBp8/ufDToSxLzR4y+O/0H/t4bQtVNw==
Nyckeltyp master
Tokenversion 1,0
Utdataauktoriseringssträng type%3dmaster%26ver%3d1.0%26sig%3dc09PEVJr
gp2uQRkr934kFbTqhByc7TVr3OHyqlu%2bc%2bc%3d

Skapa hash-signaturen för en resurstoken

Resurstoken måste genereras av en mellanliggande server. Servern fungerar som huvudnyckelskydd och genererar tidsbegränsade token för ej betrodda klienter, till exempel webbläsare.

Den här servern utför följande steg:

  1. Hanterar inkommande klientbegäranden för nya token.

  2. Verifierar klientidentiteten på ett programspecifikt sätt.

  3. Om klienten autentiseras korrekt använder den Cosmos DB-gränssnitten (SDK eller REST) för att generera en ny tidsbegränsad token och returnerar den till klienten.

Se även