Řízení přístupu v rozhraní SQL API služby Azure Cosmos DB
Azure Cosmos DB je plně spravovaná databázová služba NoSQL pro vývoj moderních aplikací. Tento článek se věnuje rozhraní SQL API pro službu Azure Cosmos DB. Přístup k prostředkům v rozhraní SQL API se řídí tokenem hlavního klíče nebo tokenem prostředku. Pro přístup k prostředku se vybraný token zahrne do autorizační hlavičky REST jako součást autorizačního řetězce.
Tokeny hlavního klíče
Token hlavního klíče je token všech přístupových klíčů, který uživatelům umožňuje úplnou kontrolu nad prostředky Služby Cosmos DB v konkrétním účtu. Hlavní klíč se vytvoří při vytváření účtu. Existují dvě sady hlavních klíčů, primární klíč a sekundární klíč. Správce účtu pak může provádět obměnu klíčů pomocí sekundárního klíče. Kromě toho může správce účtu klíče podle potřeby znovu vygenerovat. Pokyny k opětovnému generování a postupnému obnovení klíčů najdete v tématu Zabezpečený přístup k datům ve službě Azure Cosmos DB.
Tokeny prostředků
Tokeny prostředků se vytvářejí, když jsou uživatelé v databázi nastaveni s přístupovými oprávněními pro přesné řízení přístupu k prostředku, označovaného také jako prostředek oprávnění. Prostředek oprávnění obsahuje token prostředku hash vytvořený s informacemi týkajícími se cesty k prostředku a typu přístupu, ke kterým má uživatel přístup. Token prostředku oprávnění je časově vázaný a období platnosti je možné přepsat. Při akci s prostředkem oprávnění (POST, GET, PUT) se vygeneruje nový token prostředku. Informace o oprávněních a tokenech prostředků najdete v tématu Operace s oprávněními služby Cosmos DB.
Autorizační hlavička
Všechny operace REST, ať už používáte token hlavního klíče nebo token prostředku, musí obsahovat autorizační hlavičku s autorizačním řetězcem, aby bylo možné s prostředkem pracovat. Autorizační řetězec má následující formát:
type={typeoftoken}&ver={tokenversion}&sig={hashsignature}
Autorizační řetězec vypadá jako v tomto příkladu:
type=master&ver=1.0&sig=5mDuQBYA0kb70WDJoTUzSBMTG3owkC0/cEN4fqa18/s=
Části uzavřené v hranatých závorkách jsou následující:
{typeoftoken} označuje typ tokenu: master, resource nebo aad (pokud používáte RBAC služby Azure Cosmos DB).
{tokenversion} označuje verzi tokenu, aktuálně 1.0.
Pokud používáte RBAC služby Azure Cosmos DB, {hashsignature} označuje podpis tokenu hash nebo token oauth.
Autorizační řetězec by se měl před přidáním do požadavku REST zakódovat, aby se zajistilo, že neobsahuje žádné neplatné znaky. Ujistěte se, že je kódovaný jako Base64 pomocí MIME RFC2045. Hlavní klíč použitý v hashsignature by také měl být dekódován pomocí MIME RFC2045, protože je zakódován Base64. Pokud narazíte na problémy s autorizací, přečtěte si, jak diagnostikovat a řešit potíže s neautorizovanými výjimkami.
Vytvoření podpisu hashovaného tokenu pro hlavní token
Podpis hodnoty hash pro token hlavního klíče lze vytvořit z následujících parametrů: Verb, ResourceType, ResourceLink a Date.
- Sloveso představuje příkaz HTTP vašeho požadavku. Možné hodnoty jsou: get, post, put, patch, delete
Poznámka: Hodnoty musí být malé.
- Část řetězce ResourceType určuje typ prostředku, pro který je požadavek určen. Možné hodnoty:
- Databázové operace:
dbs
- Kontejnerové operace:
colls
- Uložené procedury:
sprocs
- Uživatelem definované funkce:
udfs
- Aktivační události:
triggers
- Uživatelé:
users
- Oprávnění:
permissions
- Operace na úrovni položek:
docs
- Databázové operace:
Poznámka: V hodnotách se rozlišují malá a velká písmena.
- Část řetězce ResourceLink je vlastnost identity prostředku, na který je požadavek směrován.
Hodnota ResourceLink závisí na operaci, kterou se pokoušíte provést.
Každá operace bude mít podle této konvence svůj vlastní odpovídající odkaz resourcelink:
Pokud se operace provádí s konkrétním prostředkem, pak hodnotou je propojení s tímto prostředkem. Příklady:
- Pro získání databáze použijte:
dbs/{databaseId}
- Pro získání dokumentu použijte:
dbs/{databaseId}/colls/{containerId}/docs/{docId}
- Pro získání databáze použijte:
Pokud se operace provádí se sadou prostředků (List, Create, Query), pak je hodnotou propojení nadřazeného prostředku. Příklady:
- Pro vytvoření dokumentu použijte:
dbs/{databaseId}/colls/{containerId}
- Pro vytvoření uložené procedury použijte:
dbs/{databaseId}/colls/{containerId}
- Pro vytvoření kontejneru použijte:
dbs/{databaseId}
- Pro vytvoření databáze použijte prázdný> řetězec, protože databáze nemají nadřazený prostředek.
- Pro vytvoření dokumentu použijte:
Poznámka: V názvech prostředků, na které se odkazuje jako na hodnotu ResourceLink, se rozlišují malá a velká písmena a musí odpovídat způsobu, jakým byly deklarovány v databázi. Ostatní součásti musí být malými písmeny.
Část řetězce Datum je datum a čas utc, kdy byla zpráva odeslána (ve formátu HTTP-date definovaném ve formátu RFC 7231 datum a čas), například "Út, 01 Nov 1994 08:12:31 GMT".
V jazyce C# se dá získat pomocí specifikátoru formátu R pro
DateTime.UtcNow
hodnotu.Stejné datum (ve stejném formátu) je také potřeba předat jako
x-ms-date
hlavičku požadavku.
Poznámka: V hodnotě se rozlišují malá a velká písmena.
K výpočtu podpisu používáme funkci HMAC (Hash-based Message Authentication Code) založenou na algoritmu SHA256 s tajným kódem Cosmos DB.
Datová část funkce hash je založená na 4 komponentách uvedených výše v následujícím formátu: "{verb}\n{resourceType}\n{resourceLink}\n{date}\n\n"
(všimněte si dalšího nového řádku na konci datové části).
Výsledek funkce kódování Base64 bude použit jako podpis při vytváření autorizační hlavičky pro volání.
Příklad [C#] pro platnou autorizační hlavičku:
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");
Příklad metody [C#] pro vygenerování platného autorizačního podpisu:
Kompletní ukázky pro rozhraní REST API služby Cosmos DB najdete v úložišti ukázek rozhraní REST API služby Cosmos DB na GitHubu.
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;
}
Příklad [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);
}
Příklad kódování:
Argument | Hodnota |
---|---|
Příkaz | GET |
Typ prostředku | "dbs" |
Odkaz na zdroj | "dbs/ToDoList" |
Datum | Thu, 27 Apr 2017 00:51:12 GMT |
Klíč | dsZQi3KtZmCv1ljt3VNWNm7sQUF1y5rJfC6kv5Jiwv W0EndXdDku/dkKBp8/ufDToSxLzR4y+O/0H/t4bQtVNw== |
Typ klíče | master |
Verze tokenu | 1.0 |
Výstupní autorizační řetězec | type%3dmaster%26ver%3d1.0%26sig%3dc09PEVJr gp2uQRkr934kFbTqhByc7TVr3OHyqlu%2bc%2bc%3d |
Vytvoření podpisu hodnoty hash pro token prostředku
Tokeny prostředků musí být generovány zprostředkujícím serverem. Server slouží jako strážce hlavního klíče a generuje časově omezené tokeny pro nedůvěryhodné klienty, jako jsou webové prohlížeče.
Tento server provede následující kroky:
Zpracovává příchozí požadavky klientů na nové tokeny.
Ověřuje identitu klienta způsobem specifickým pro aplikaci.
Pokud se klient úspěšně ověří, použije rozhraní Cosmos DB (SDK nebo REST) k vygenerování nového časově omezeného tokenu a jeho vrácení klientovi.