Azure Cosmos DB SQL API의 액세스 제어

Azure Cosmos DB는 최신 앱 개발을 위한 완전 관리형 NoSQL 데이터베이스 서비스입니다. 이 문서에서는 Azure Cosmos DB용 SQL API에 대해 설명합니다. SQL API에서 리소스에 대한 액세스는 마스터 키 토큰 또는 리소스 토큰에 의해 제어됩니다. 리소스에 액세스하기 위해 선택한 토큰이 REST 인증 헤더에 권한 부여 문자열의 일부로 포함됩니다.

마스터 키 토큰

master 키 토큰은 사용자가 특정 계정에서 Cosmos DB 리소스를 완전히 제어할 수 있는 모든 액세스 키 토큰입니다. 마스터 키는 계정을 만드는 동안 만들어집니다. 마스터 키에는 기본 키와 보조 키라는 두 가지 집합이 있습니다. 계정의 관리자는 보조 키를 사용하여 키 회전을 실행할 수 있으며 필요한 경우 키를 다시 생성할 수도 있습니다. 키를 다시 생성하고 롤링하는 방법에 대한 지침은 Azure Cosmos DB의 데이터에 대한 액세스 보안을 참조하세요.

리소스 토큰

리소스 토큰은 데이터베이스의 사용자가 리소스에 대한 정확한 액세스 제어(권한 리소스라고도 함)에 대한 액세스 권한으로 설정되면 만들어집니다. 권한 리소스에는 사용자가 액세스할 수 있는 리소스 경로 및 액세스 유형에 대한 정보를 사용하여 생성된 해시 리소스 토큰이 포함됩니다. 사용 권한 리소스 토큰은 시간 제한이 있으며 유효 기간은 재정의될 수 있습니다. 사용 권한 리소스가 (POST, GET, PUT)에서 적용될 때 새 리소스 토큰이 생성됩니다. 권한 및 리소스 토큰에 대한 자세한 내용은 Cosmos DB 권한에 대한 작업을 참조하세요.

권한 부여 헤더

master 키 토큰 또는 리소스 토큰을 사용하는 모든 REST 작업에는 리소스와 상호 작용하기 위해 권한 부여 문자열이 있는 권한 부여 헤더가 포함되어야 합니다. 권한 부여 문자열의 형식은 다음과 같습니다.

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

권한 부여 문자열은 다음 예제와 같습니다.

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

중 괄호로 묶인 부분은 다음과 같습니다.

  • {typeoftoken}은 토큰 유형(master, 리소스 또는 aad(Azure Cosmos DB RBAC를 사용하는 경우)을 나타냅니다.

  • {tokenversion}은 토큰의 버전(현재 1.0)을 표시합니다.

  • {hashsignature}는 Azure Cosmos DB RBAC를 사용하는 경우 해시된 토큰 서명 또는 oauth 토큰을 표시합니다.

권한 부여 문자열은 REST 요청에 추가되기 전에 잘못된 문자를 포함하지 않도록 하기 위해 인코딩되어야 합니다. MIME RFC2045를 사용하여 Base64로 인코딩되었는지 확인합니다. 또한 해시 서명에 사용되는 master 키는 Base64로 인코딩된 MIME RFC2045를 사용하여 디코딩해야 합니다. 권한 부여에 문제가 있는 경우 권한 없는 예외를 진단하고 해결하는 방법을 참조하세요.

master 토큰에 대한 해시된 토큰 서명 생성

master 키 토큰에 대한 해시 서명은 동사, ResourceType, ResourceLinkDate 매개 변수에서 생성할 수 있습니다.

  1. 동사는 요청의 HTTP 동사를 나타냅니다. 가능한 값은 get, post, put, patch, delete입니다.

참고:: 값은 소문자여야 합니다.

  1. 문자열의 ResourceType 부분은 요청이 적용되는 리소스의 유형을 식별합니다. 가능한 값은 다음과 같습니다.
    • 데이터베이스 작업: dbs
    • 컨테이너 작업: colls
    • 저장 프로시저: sprocs
    • 사용자 정의 함수: udfs
    • 트리거: triggers
    • 사용자: users
    • 권한을: permissions
    • 항목 수준 작업: docs

참고: 값은 대/소문자를 구분하며 소문자여야 합니다.

  1. 문자열의 ResourceLink 부분은 요청이 전달되는 리소스의 ID 속성입니다. ResourceLink 값은 실행하려는 작업에 따라 달라집니다. 각 작업에는 다음 규칙에 따라 고유한 해당 ResourceLink가 있습니다.
    • 특정 리소스에 대해 작업을 수행하는 경우 값은 해당 리소스에 대한 링크입니다. 예제:

      • 데이터베이스 가져오기 사용: dbs/{databaseId}
      • 문서 가져오기의 경우 다음을 사용합니다. dbs/{databaseId}/colls/{containerId}/docs/{docId}
    • 리소스 집합(목록, 만들기, 쿼리)에 대해 작업을 수행하는 경우 값은 부모 리소스의 링크입니다. 예제:

      • 문서 만들기의 경우 다음을 사용합니다. dbs/{databaseId}/colls/{containerId}
      • 저장 프로시저 만들기의 경우 다음을 사용합니다. dbs/{databaseId}/colls/{containerId}
      • 컨테이너 만들기의 경우 다음을 사용합니다. dbs/{databaseId}
      • 데이터베이스 만들기 사용: "" -> 데이터베이스에 부모 리소스가 없으므로 빈 문자열

참고: ResourceLink 값의 일부로 참조되는 리소스 이름은 대/소문자를 구분하며 데이터베이스에서 선언된 방식의 대/소문자와 일치해야 합니다. 다른 구성 요소는 소문자여야 합니다.

  1. 문자열의 날짜 부분은 메시지가 전송된 UTC 날짜 및 시간입니다( RFC 7231 날짜/시간 형식으로 정의된 "HTTP 날짜" 형식)(예: "Tue, 1994년 11월 11일 08:12:31 GMT").

    C#에서는 값에 "R" 형식 지정자를 DateTime.UtcNow 사용하여 가져올 수 있습니다.

    동일한 날짜(동일한 형식)도 요청의 헤더로 x-ms-date 전달되어야 합니다.

참고: 값은 대/소문자를 구분하며 모두 소문자여야 합니다.

서명을 계산하기 위해 CosmosDB 키를 비밀로 사용하여 SHA256 기반 해시 기반 HMAC(메시지 인증 코드) 함수를 사용합니다.

해시 함수에 대한 페이로드는 다음 형식 "{verb}\n{resourceType}\n{resourceLink}\n{date}\n\n" 을 사용하여 위에 제시된 4개의 구성 요소를 기반으로 합니다(페이로드 끝에 새 추가 줄을 적어 두세요).

함수의 Base64로 인코딩된 결과는 호출에 대한 Authorization 헤더를 생성할 때 서명으로 사용됩니다.

유효한 권한 부여 헤더에 대한 예제 [C#] :

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

유효한 권한 부여 서명을 생성하는 예제 [C#] 메서드:

Cosmos DB REST API에 대한 전체 샘플을 보려면 GitHub의 Cosmos DB REST API 샘플 리포지토리를 방문하세요.

  
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;
}
  

예제 [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
dsZQi3KtZmCv1ljt3VNWNm7sQUF1y5rJfC6kv5Jiwv
W0EndXdDku/dkKBp8/ufDToSxLzR4y+O/0H/t4bQtVNw==
키 유형 master
토큰 버전 1.0
출력 권한 부여 문자열 type%3dmaster%26ver%3d1.0%26sig%3dc09PEVJr
gp2uQRkr934kFbTqhByc7TVr3OHyqlu%2bc%2bc%3d

리소스 토큰에 대한 해시 서명 생성

리소스 토큰은 중간 서버에서 생성해야 합니다. 서버는 master 키 보호자 역할을 하며 웹 브라우저와 같은 신뢰할 수 없는 클라이언트에 대한 시간 제한 토큰을 생성합니다.

이 서버는 다음 단계를 수행합니다.

  1. 새 토큰에 대한 들어오는 클라이언트 요청을 처리합니다.

  2. 애플리케이션별 방식으로 클라이언트 ID를 확인합니다.

  3. 클라이언트가 성공적으로 인증하는 경우 Cosmos DB 인터페이스(SDK 또는 REST)를 사용하여 시간 제한 토큰을 새로 생성하고 클라이언트에 반환합니다.

참고 항목