Azure Cosmos DB SQL API のアクセス制御

Azure Cosmos DB は、グローバル分散型のマルチモデル データベースであり、複数の API でサポートされています。 この記事では、Azure Cosmos DB 用の SQL API について説明します。 SQL API のリソースへのアクセスは、マスター キー トークンまたはリソース トークンで制御します。 リソースにアクセスするために、選択されたトークンは、承認文字列の一部として REST の Authorization ヘッダーに含められます。

マスター キー トークン

マスター キー トークンは、ユーザーが特定のアカウント内の DB リソースを完全Cosmos制御できるすべてのアクセス キー トークンです。 マスター キーは、アカウントの作成時に作成されます。 マスター キーには、プライマリ キーとセカンダリ キーの 2 種類があります。 アカウントの管理者は、セカンダリ キーを使用してキーをローテーションさせることができます。 さらに、必要に応じてキーを再生成することもできます。 キーの再生成とローリングの手順については、「Secure access to data in Azure Cosmos DB 」を参照してください

リソース トークン

リソース トークンは、データベース内のユーザーがアクセス許可を使用して設定され、リソースに対する正確なアクセス制御 (アクセス許可リソースとも呼ばれる) が設定されると作成されます。 アクセス許可リソースには、ユーザーがアクセスできるリソース パスとアクセスの種類に関する情報で構築されたハッシュ リソース トークンが含まれます。 アクセス許可リソース トークンには期限があり、有効期間はオーバーライドできます。 アクセス許可リソースがアクション (POST、GET、PUT) に基づいて実行されると、新しいリソース トークンが生成されます。 アクセス許可とリソース トークンの詳細については、「 OPERATIONS on Cosmos DB Permissions 」を参照してください

Authorization header (Authorization ヘッダー)

リソースと対話するには、マスター キー トークンまたはリソース トークンを使用している場合でも、すべての REST 操作に承認ヘッダーと承認文字列を含める必要があります。 承認文字列の形式は次のとおりです。

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

承認文字列は次の例のようになります。

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

角かっこで囲まれた部分は、次のとおりです。

  • {typeoftoken} は、トークンの種類 (マスター、リソース、または aad) を表します (Azure Cosmos DB RBAC を使用している場合)。

  • {tokenversion} は、トークンのバージョン (現在は 1.0) を表します

  • {hashsignature} は、Azure Cosmos DB RBAC を使用している場合は、ハッシュされたトークン署名または oauth トークンを表します

承認文字列は、無効な文字を含まないようにするために、REST 要求に追加する前にエンコードする必要があります。 MIME RFC2045 を使用して Base64 エンコード済みである必要があります。 また、ハッシュ署名で使用されるマスター キーは、Base64 でエンコードされた MIME RFC2045 を使用してデコードする必要があります。 承認に関する問題が発生した場合は、「承認されていない例外を診断してトラブルシューティング する」を参照してください。

マスター トークンのハッシュされたトークン署名の構築

マスター キー トークンのハッシュ署名は、Verb、ResourceType、ResourceLink、Date のパラメーター から 構築 できます

マスター キー トークンのハッシュ署名を構築する場合は、次のことを念頭に置きます。

  1. 文字列 の Verb 部分は、GET、POST、PUT などの HTTP 動詞です。

  2. 文字列 の ResourceType 部分は、要求のリソースの種類 (例: ) を識別します。 "dbs"、"colls"、"docs"。

  3. 文字列 の ResourceLink 部分は、要求が送信されるリソースの ID プロパティです。 ResourceLink では 、リソースの ID の大文字と小文字を維持する必要があります。 たとえば、コレクションの場合、"dbs/MyDatabase/colls/MyCollection" のようになります。

  4. 文字列 の Date 部分は、メッセージが送信された UTC 日時です (RFC 7231日付/時刻形式で定義されている "HTTP-date" 形式)。 Tue, 01 Nov 1994 08:12:31 GMT C# では、DateTime.UtcNow 値の "R" 書式指定子を使用して取得できます。 この同じ日付 (同じ形式) も、要求で x-ms-date ヘッダーとして渡す必要があります。

  5. 表示される新しい行文字 (\n) はすべて、最後の空の文字列 ("") を含む署名文字列内で必要です。

要求の署名文字列を DB に対してエンコードするにはCosmos形式を使用します。

StringToSign = Verb.toLowerCase() + "\n" + ResourceType.toLowerCase() + "\n" + ResourceLink + "\n" + Date.toLowerCase() + "\n" + "" + "\n";

有効な Authorization ヘッダーを生成する例 [C#] メソッド:

このメソッドの使い方の例と、操作の種類ごとに各パラメーターに渡す値については、以下を参照してください。
.NET クライアントからの REST の使用

  
string GenerateAuthToken(string verb, string resourceType, string resourceId, string date, string key, string keyType, string tokenVersion)  
{  
    var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) };  
    
    verb = verb ?? "";  
    resourceType = resourceType ?? "";
    resourceId = resourceId ?? "";
  
    string payLoad = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}\n{1}\n{2}\n{3}\n{4}\n",  
            verb.ToLowerInvariant(),  
            resourceType.ToLowerInvariant(),  
            resourceId,  
            date.ToLowerInvariant(),  
            ""  
    );  
  
    byte[] hashPayLoad = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad));  
    string signature = Convert.ToBase64String(hashPayLoad);  
  
    return System.Web.HttpUtility.UrlEncode(String.Format(System.Globalization.CultureInfo.InvariantCulture, "type={0}&ver={1}&sig={2}",  
        keyType,  
        tokenVersion,  
        signature));  
}  
  

例 [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"
Date 2017 年 4 月 27 日 (木) 00:51:12 GMT
Key dsZQi3KtZmCv1kvt3VNWNm7sQUF1y5rJfC6kv5Jiwv
W0EndXdDku/dkKBp8/ufDToSxLzR4y+O/0H/t4bQtVNw==
キーの種類 master
トークンのバージョン 1.0
出力承認文字列 type%3dmaster%26ver%3d1.0%26sig%3dc09PEV アクセス
gp2uQRkr934kFbTqhByc7TVr3OHyqlu%2bc%2bc%3d

リソース トークンのハッシュ署名の構築

リソース トークンは、中間サーバーによって生成される必要があります。 サーバーはマスター キー ガーディアンとして機能し、Web ブラウザーなどの信頼されていないクライアントの時間制限付きトークンを生成します。

このサーバーは、次の手順を実行します。

  1. 新しいトークンの受信クライアント要求を処理します。

  2. アプリケーション固有の方法でクライアント ID を検証します。

  3. クライアントが正常に認証されると、Cosmos DB インターフェイス (SDK または REST) を使用して新しい期間限定トークンが生成され、クライアントに返されます。

参照