Partilhar via


Controlo de acesso na API SQL do Azure Cosmos DB

O Azure Cosmos DB é um serviço de base de dados NoSQL totalmente gerido para o desenvolvimento de aplicações modernas. Este artigo abrange a API SQL para o Azure Cosmos DB. O acesso aos recursos na API SQL é regido por um token de chave mestra ou token de recurso. Para aceder a um recurso, o token selecionado está incluído no cabeçalho de autorização REST, como parte da cadeia de autorização.

Tokens de chave mestra

O token de chave mestra é o token de todas as chaves de acesso que permite aos utilizadores ter controlo total dos recursos do Cosmos DB numa conta específica. A chave mestra é criada durante a criação de uma conta. Existem dois conjuntos de chaves mestras, a chave primária e a chave secundária. Em seguida, o administrador da conta pode exercer a rotação de chaves com a chave secundária. Além disso, o administrador de conta também pode regenerar as chaves conforme necessário. Para obter instruções sobre regeneração e chaves sem interrupção, veja Proteger o acesso aos dados no Azure Cosmos DB.

Tokens de recursos

Os tokens de recursos são criados quando os utilizadores numa base de dados são configurados com permissões de acesso para um controlo de acesso preciso num recurso, também conhecido como recurso de permissão. Um recurso de permissão contém um símbolo de recurso de hash construído com a informação relativa à trajetória de recurso e tipo de acesso a que um utilizador tem acesso. O token de recurso de permissão está vinculado ao tempo e o período de validade pode ser substituído. Quando um recurso de permissão é implementado em (POST, GET, PUT), é gerado um novo token de recurso. Para obter informações sobre permissões e tokens de recursos, veja Operations on Cosmos DB Permissions (Operações nas Permissões do Cosmos DB).

Cabeçalho de autorização

Todas as operações REST, quer esteja a utilizar um token de chave mestra ou um token de recurso, têm de incluir o cabeçalho de autorização com a cadeia de autorização para interagir com um recurso. A cadeia de autorização tem o seguinte formato:

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

Uma cadeia de autorização tem o seguinte aspeto:

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

As partes entre parênteses retos são as seguintes:

  • {typeoftoken} denota o tipo de token: master, resource ou aad(se estiver a utilizar o RBAC do Azure Cosmos DB).

  • {tokenversion} indica a versão do token, atualmente 1.0.

  • O {hashsignature} denota a assinatura de token hash ou o token oauth se estiver a utilizar o RBAC do Azure Cosmos DB.

A cadeia de autorização deve ser codificada antes de a adicionar ao pedido REST para garantir que não contém carateres inválidos. Certifique-se de que está codificado em Base64 com MIME RFC2045. Além disso, a chave mestra utilizada no hashsignature deve ser descodificada com o MIME RFC2045, uma vez que está codificada em Base64. Se vir problemas com a autorização, veja Como Diagnosticar e resolver problemas de exceções não autorizadas.

Construir a assinatura de token com hash para um token principal

A assinatura hash do token de chave mestra pode ser construída a partir dos seguintes parâmetros: Verbo, ResourceType, ResourceLink e Date.

  1. O Verbo representa o verbo HTTP do seu pedido. Os valores possíveis são: get, post, put, patch, delete

Nota: os valores têm de estar em minúsculas.

  1. A parte ResourceType da cadeia identifica o tipo de recurso para o qual o pedido se destina. Os valores possíveis são:
    • Operações da base de dados: dbs
    • Operações de contentor: colls
    • Procedimentos Armazenados: sprocs
    • Funções Definidas pelo Utilizador: udfs
    • Acionadores: triggers
    • Utilizadores: users
    • Permissões: permissions
    • Operações ao nível do item: docs

Nota: Os valores são sensíveis às maiúsculas e minúsculas.

  1. A parte ResourceLink da cadeia é a propriedade de identidade do recurso para o qual o pedido é direcionado. O valor ResourceLink depende da operação que está a tentar executar. Cada operação terá o seu próprio ResourceLink correspondente ao seguir esta convenção:
    • Se a operação for efetuada num recurso específico, o valor será a ligação para esse recurso. Exemplos:

      • Para obter a utilização da Base de Dados: dbs/{databaseId}
      • Para obter a utilização do Documento: dbs/{databaseId}/colls/{containerId}/docs/{docId}
    • Se a operação for efetuada num conjunto de recursos (Lista, Criar, Consulta), o valor será a ligação do recurso principal. Exemplos:

      • Para a utilização de Criar Documento: dbs/{databaseId}/colls/{containerId}
      • Para criar procedimento armazenado, utilize: dbs/{databaseId}/colls/{containerId}
      • Para Criar um Contentor, utilize: dbs/{databaseId}
      • Para a utilização de Criar Base de Dados: "" –> uma cadeia vazia, uma vez que as Bases de Dados não têm um recurso principal

Nota: Os nomes de recursos que estão a ser referenciados como parte do valor ResourceLink são sensíveis a maiúsculas e minúsculas e têm de corresponder à forma como foram declarados na base de dados. Os outros componentes têm de estar em minúsculas.

  1. A parte Data da cadeia é a data e hora UTC em que a mensagem foi enviada (no formato "data HTTP", conforme definido pelos Formatos de Data/Hora RFC 7231), por exemplo, "Tue, 01 nov 1994 08:12:31 GMT".

    Em C#, pode ser obtido com o especificador de formato "R" no DateTime.UtcNow valor.

    Esta mesma data (no mesmo formato) também tem de ser transmitida como x-ms-date cabeçalho no pedido.

Nota: O valor é sensível às maiúsculas e minúsculas e tem de estar em minúsculas.

Para calcular a assinatura, utilizamos a função Código de Autenticação de Mensagens (HMAC) baseado em Hash baseado em SHA256 com a Chave do CosmosDB como segredo.

O payload da função hashing baseia-se nos quatro componentes apresentados acima com o seguinte formato: "{verb}\n{resourceType}\n{resourceLink}\n{date}\n\n" (tenha em atenção a nova linha extra no final do payload).

O resultado codificado de Base64 da função será utilizado como a assinatura ao construir o cabeçalho Autorização da chamada.

Exemplo [C#] para um cabeçalho de Autorização válido:

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

Exemplo de método [C#] para gerar uma assinatura de Autorização válida:

Para ver exemplos completos da API REST do Cosmos DB, veja Repositório de Exemplos de API REST do Cosmos DB no 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;
}
  

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

Codificação de exemplo:

Argumento Valor
Verbo GET
Tipo de Recurso "dbs"
Ligação de Recurso "dbs/ToDoList"
Date Thu, 27 Abr 2017 00:51:12 GMT
Chave dsZQi3KtZmCv1ljt3VNWNm7sQUF1y5rJfC6kv5Jiwv
W0EndXdDku/dkKBp8/ufDToSxLzR4y+O/0H/t4bQtVNw==
Tipo de Chave master
Versão do Token 1.0
Cadeia de Autorização de Saída type%3dmaster%26ver%3d1.0%26sig%3dc09PEVJr
gp2uQRkr934kFbTqhByc7TVr3OHyqlu%2bc%2bc%3d

Construindo a assinatura de hash para um token de recurso

Os tokens de recursos têm de ser gerados por um servidor intermédio. O servidor serve como guardião de chave mestra e gera tokens com restrição de tempo para clientes não fidedignos, como browsers.

Este servidor executa os seguintes passos:

  1. Processa pedidos de cliente recebidos para novos tokens.

  2. Verifica a identidade do cliente de forma específica da aplicação.

  3. Se o cliente se autenticar com êxito, utiliza as interfaces do Cosmos DB (SDK ou REST) para gerar um novo token limitado no tempo e devolve-o ao cliente.

Consulte também