為您的 Azure Cosmos DB 帳戶設定 Microsoft Entra ID 的角色型存取控制

適用於:NoSQL

注意

本文說明 Azure Cosmos DB 中資料平面作業的角色型存取控制。 若您使用的是管理平面作業,請參閱適用於您管理平面作業的角色型存取控制文章。

Azure Cosmos DB 公開內建的角色型存取控制系統,可讓您:

  • 使用 Microsoft Entra 身分識別驗證您的資料要求。
  • 使用更精細的角色型權限模型來授權資料要求。

概念

Azure Cosmos DB 資料平面角色型存取控制奠基於通常存在 Azure 角色型存取控制等其他角色型存取控制系統中的概念:

  • 權限模型是由一組動作所組成;這些動作都各自對應至一或多個資料庫作業。 動作的範例包括讀取項目、寫入項目或執行查詢等。
  • Azure Cosmos DB 使用者建立包含允許動作清單的角色定義
  • 角色定義會透過角色指派獲指派至特定的 Microsoft Entra 身分識別。 角色指派也會定義角色定義適用的範圍;目前有三個範圍,分別是:
    • Azure Cosmos DB 帳戶、
    • Azure Cosmos DB 資料庫、
    • Azure Cosmos DB 容器。

Diagram of common role-based access control concepts including role definitions, role assignments, and principals.

權限模型

重要

此權限模型僅涵蓋涉及讀取與寫入資料的資料庫作業。 其「不會」涵蓋管理資源的任何一種管理作業,包括:

  • 建立/取代/刪除資料庫
  • 建立/取代/刪除容器
  • 讀取/取代容器輸送量
  • 建立/取代/刪除/讀取預存程序
  • 建立/取代/刪除/讀取觸發程序
  • 建立/取代/刪除/讀取使用者定義函數

您「無法使用任何 Azure Cosmos DB 資料平面 SDK」,驗證具有 Microsoft Entra 身分識別的管理作業。 相反地,您必須透過下列其中一個選項來使用 Azure 角色型存取控制

讀取資料庫與讀取容器會視為中繼資料要求。 可依照下一節所述的方式授與這些作業的存取權。

下表會列出權限模型公開的所有動作。

名稱 對應的資料庫作業
Microsoft.DocumentDB/databaseAccounts/readMetadata 讀取帳戶中繼資料。 如需詳細資料,請參閱中繼資料要求
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/create 建立新的項目。
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read 依其識別碼與分割區索引鍵 (讀取點) 讀取個別項目。
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/replace 取代現有的項目。
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/upsert "Upsert" 項目。 如果項目不存在,則此作業會建立項目,或如果項目存在,則會取代該項目。
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/delete 刪除項目。
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery 執行 SQL 查詢
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed 從容器的變更摘要讀取。 使用 SDK 執行 SQL 查詢
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeStoredProcedure 執行預存程序
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/manageConflicts 管理多重寫入區域帳戶的衝突 (也就是列出及刪除衝突摘要中的項目)。

注意

透過 SDK 執行查詢時,需要 Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQueryMicrosoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed 權限。

容器與項目等級都支援萬用字元:

  • Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*
  • Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*

中繼資料要求

Azure Cosmos DB SDK 會在初始化期間發出唯讀的中繼資料要求,並提供特定的資料要求。 這些要求會擷取各種設定詳細資料,例如:

  • 您帳戶的全域設定,其中包括帳戶適用的 Azure 區域。
  • 容器或其索引原則的分割區索引鍵。
  • 組成容器及其位址的實體分割區清單。

這些要求「不會」擷取您在帳戶中儲存的任何資料。

為了確保權限模型的最佳透明度,Microsoft.DocumentDB/databaseAccounts/readMetadata 動作會明確地涵蓋這些中繼資料要求。 此動作在透過其中一個 Azure Cosmos DB SDK 存取 Azure Cosmos DB 帳戶的每個情況下,都應該獲得允許。 其可在 Azure Cosmos DB 階層 (也就是帳戶、資料庫或容器) 中的任何等級獲得指派 (透過角色指派)。

Microsoft.DocumentDB/databaseAccounts/readMetadata 動作允許的實際中繼資料要求取決於動作獲指派的範圍:

範圍 動作允許的要求
客戶​​ - 列出帳戶下的資料庫
- 針對帳戶下的每個資料庫,資料庫範圍中允許的動作
Database - 讀取資料庫中繼資料
- 列出資料庫下的容器
- 針對資料庫下的每個容器,容器範圍中允許的動作
容器 - 讀取容器中繼資料
- 列出容器底下的實體分割區
- 解析每個實體分割區的位址

重要

此動作的中繼資料中不包含輸送量。

內建角色定義

Azure Cosmos DB 公開兩個內建角色定義:

重要

這裡的角色定義一詞是指 Azure Cosmos DB 專屬的角色定義。 這些與 Azure 角色型存取控制角色定義不同。

ID 名稱 包含的動作
00000000-0000-0000-0000-000000000001 Cosmos DB 內建資料讀者 Microsoft.DocumentDB/databaseAccounts/readMetadata
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed
00000000-0000-0000-0000-000000000002 Cosmos DB 內建資料參與者 Microsoft.DocumentDB/databaseAccounts/readMetadata
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*

建立自訂角色定義

建立自訂角色定義時,您必須提供:

  • Azure Cosmos DB 帳戶名稱。
  • 包含您帳戶的資源群組。
  • 角色定義的類型:CustomRole
  • 角色定義的名稱。
  • 您希望角色允許的動作清單。
  • 可以指派角色定義的一或多個範圍;支援的範圍為:
    • / (帳戶層級),
    • /dbs/<database-name> (容器層級),
    • /dbs/<database-name>/colls/<container-name> (容器層級),

注意

所述作業的適用對象:

使用 Azure PowerShell

建立名為 MyReadOnlyRole 的角色,其中僅包含讀取動作:

$resourceGroupName = "<myResourceGroup>"
$accountName = "<myCosmosAccount>"
New-AzCosmosDBSqlRoleDefinition -AccountName $accountName `
    -ResourceGroupName $resourceGroupName `
    -Type CustomRole -RoleName MyReadOnlyRole `
    -DataAction @( `
        'Microsoft.DocumentDB/databaseAccounts/readMetadata',
        'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read', `
        'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery', `
        'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed') `
    -AssignableScope "/"

建立名為 MyReadWriteRole 的角色,其中包含所有動作:

New-AzCosmosDBSqlRoleDefinition -AccountName $accountName `
    -ResourceGroupName $resourceGroupName `
    -Type CustomRole -RoleName MyReadWriteRole `
    -DataAction @( `
        'Microsoft.DocumentDB/databaseAccounts/readMetadata',
        'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*', `
        'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*') `
    -AssignableScope "/"

列出您已建立的角色定義,以擷取其識別碼:

Get-AzCosmosDBSqlRoleDefinition -AccountName $accountName `
    -ResourceGroupName $resourceGroupName
RoleName         : MyReadWriteRole
Id               : /subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAcc
                   ounts/<myCosmosAccount>/sqlRoleDefinitions/<roleDefinitionId>
Type             : CustomRole
Permissions      : {Microsoft.Azure.Management.CosmosDB.Models.Permission}
AssignableScopes : {/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAc
                   counts/<myCosmosAccount>}

RoleName         : MyReadOnlyRole
Id               : /subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAcc
                   ounts/<myCosmosAccount>/sqlRoleDefinitions/<roleDefinitionId>
Type             : CustomRole
Permissions      : {Microsoft.Azure.Management.CosmosDB.Models.Permission}
AssignableScopes : {/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAc
                   counts/<myCosmosAccount>}

使用 Azure CLI

建立名為 MyReadOnlyRole 的角色,其中只會在名為 role-definition-ro.json 的檔案中包含讀取動作:

{
    "RoleName": "MyReadOnlyRole",
    "Type": "CustomRole",
    "AssignableScopes": ["/"],
    "Permissions": [{
        "DataActions": [
            "Microsoft.DocumentDB/databaseAccounts/readMetadata",
            "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read",
            "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery",
            "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed"
        ]
    }]
}
resourceGroupName='<myResourceGroup>'
accountName='<myCosmosAccount>'
az cosmosdb sql role definition create --account-name $accountName --resource-group $resourceGroupName --body @role-definition-ro.json

建立名為 MyReadWriteRole 的角色,其中包含 role-definition-rw.json 檔案中的所有動作:

{
    "RoleName": "MyReadWriteRole",
    "Type": "CustomRole",
    "AssignableScopes": ["/"],
    "Permissions": [{
        "DataActions": [
            "Microsoft.DocumentDB/databaseAccounts/readMetadata",
            "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
            "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*"
        ]
    }]
}
az cosmosdb sql role definition create --account-name $accountName --resource-group $resourceGroupName --body @role-definition-rw.json

列出您已建立的角色定義,以擷取其識別碼:

az cosmosdb sql role definition list --account-name $accountName --resource-group $resourceGroupName
[
  {
    "assignableScopes": [
      "/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAccounts/<myCosmosAccount>"
    ],
    "id": "/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAccounts/<myCosmosAccount>/sqlRoleDefinitions/<roleDefinitionId>",
    "name": "<roleDefinitionId>",
    "permissions": [
      {
        "dataActions": [
          "Microsoft.DocumentDB/databaseAccounts/readMetadata",
          "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
          "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*"
        ],
        "notDataActions": []
      }
    ],
    "resourceGroup": "<myResourceGroup>",
    "roleName": "MyReadWriteRole",
    "sqlRoleDefinitionGetResultsType": "CustomRole",
    "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions"
  },
  {
    "assignableScopes": [
      "/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAccounts/<myCosmosAccount>"
    ],
    "id": "/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAccounts/<myCosmosAccount>/sqlRoleDefinitions/<roleDefinitionId>",
    "name": "<roleDefinitionId>",
    "permissions": [
      {
        "dataActions": [
          "Microsoft.DocumentDB/databaseAccounts/readMetadata",
          "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read",
          "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery",
          "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed"
        ],
        "notDataActions": []
      }
    ],
    "resourceGroup": "<myResourceGroup>",
    "roleName": "MyReadOnlyRole",
    "sqlRoleDefinitionGetResultsType": "CustomRole",
    "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions"
  }
]

使用 Azure Resource Manager 範本

如需使用 Azure Resource Manager 範本來建立角色定義的參考與範例,請參閱 Microsoft.DocumentDB databaseAccounts/sqlRoleDefinitions

建立角色指派

您可以將內建或自訂角色定義與 Microsoft Entra 身分識別建立關聯。 建立角色指派時,您必須提供:

  • Azure Cosmos DB 帳戶名稱。

  • 包含您帳戶的資源群組。

  • 要指派的角色定義識別碼。

  • 應獲指派角色定義之身分識別的主體識別碼。

  • 角色指派的範圍;支援的範圍為:

    • / (帳戶層級)
    • /dbs/<database-name> (資料庫等級)
    • /dbs/<database-name>/colls/<container-name> (容器層級)

    該範圍必須符合,或是其中一個角色定義可指派範圍的子範圍。

注意

若您想要為服務主體建立角色指派,請務必使用其物件識別碼,該識別碼可在 [Microsoft Entra ID] 入口網站刀鋒視窗的 [企業應用程式] 區段中找到。

注意

所述作業的適用對象:

使用 Azure PowerShell

將角色指派給身分識別:

$resourceGroupName = "<myResourceGroup>"
$accountName = "<myCosmosAccount>"
$readOnlyRoleDefinitionId = "<roleDefinitionId>" # as fetched above
# For Service Principals make sure to use the Object ID as found in the Enterprise applications section of the Azure Active Directory portal blade.
$principalId = "<aadPrincipalId>"
New-AzCosmosDBSqlRoleAssignment -AccountName $accountName `
    -ResourceGroupName $resourceGroupName `
    -RoleDefinitionId $readOnlyRoleDefinitionId `
    -Scope "/" `
    -PrincipalId $principalId

使用 Azure CLI

將角色指派給身分識別:

resourceGroupName='<myResourceGroup>'
accountName='<myCosmosAccount>'
readOnlyRoleDefinitionId='<roleDefinitionId>' # as fetched above
# For Service Principals make sure to use the Object ID as found in the Enterprise applications section of the Azure Active Directory portal blade.
principalId='<aadPrincipalId>'
az cosmosdb sql role assignment create --account-name $accountName --resource-group $resourceGroupName --scope "/" --principal-id $principalId --role-definition-id $readOnlyRoleDefinitionId

使用 Bicep/Azure Resource Manager 範本

針對使用 Bicep 範本的內建指派:

resource sqlRoleAssignment 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2023-04-15' = {
  name: guid(<roleDefinitionId>, <aadPrincipalId>, <databaseAccountResourceId>)
  parent: databaseAccount
  properties:{
    principalId: <aadPrincipalId>
    roleDefinitionId: '/${subscription().id}/resourceGroups/<databaseAccountResourceGroup>/providers/Microsoft.DocumentDB/databaseAccounts/<myCosmosAccount>/sqlRoleDefinitions/<roleDefinitionId>'
    scope: <databaseAccountResourceId>
  }
}

如需使用 Azure Resource Manager 範本來建立角色定義的參考與範例,請參閱 Microsoft.DocumentDB databaseAccounts/sqlRoleAssignments

使用 Microsoft Entra ID 初始化 SDK

若要使用您的應用程式中的 Azure Cosmos DB 角色型存取控制,您必須更新初始化 Azure Cosmos DB SDK 的方式。 您必須傳遞 TokenCredential 類別的執行個體,而不是傳遞您帳戶的主要金鑰。 此執行個體會為 Azure Cosmos DB SDK 提供必要的內容,以代表您欲使用的身分識別擷取 Microsoft Entra 權杖。

您建立 TokenCredential 執行個體的方式已超出本文的範圍。 根據您要使用的 Microsoft Entra 身分識別類型 (使用者主體、服務主體、群組等),您可以利用許多方式建立該等執行個體。 最重要的是,您的 TokenCredential 執行個體必須解析為您已指派角色的身分識別 (主體識別碼)。 您可以找到建立 TokenCredential 類別的範例:

下列範例會搭配 ClientSecretCredential 執行個體使用服務主體。

在 .NET 中

.NET SDK 第 3 版目前支援 Azure Cosmos DB 角色型存取控制。

TokenCredential servicePrincipal = new ClientSecretCredential(
    "<azure-ad-tenant-id>",
    "<client-application-id>",
    "<client-application-secret>");
CosmosClient client = new CosmosClient("<account-endpoint>", servicePrincipal);

使用 Java

Java SDK 第 4 版目前支援 Azure Cosmos DB 角色型存取控制。

TokenCredential ServicePrincipal = new ClientSecretCredentialBuilder()
    .authorityHost("https://login.microsoftonline.com")
    .tenantId("<azure-ad-tenant-id>")
    .clientId("<client-application-id>")
    .clientSecret("<client-application-secret>")
    .build();
CosmosAsyncClient Client = new CosmosClientBuilder()
    .endpoint("<account-endpoint>")
    .credential(ServicePrincipal)
    .build();

使用 JavaScript

JavaScript SDK 第 3 版目前支援 Azure Cosmos DB 角色型存取控制。

const servicePrincipal = new ClientSecretCredential(
    "<azure-ad-tenant-id>",
    "<client-application-id>",
    "<client-application-secret>");
const client = new CosmosClient({
    endpoint: "<account-endpoint>",
    aadCredentials: servicePrincipal
});

在 Python 中

Python SDK 4.3.0b4 版和更新版本支援 Azure Cosmos DB 角色型存取控制。

aad_credentials = ClientSecretCredential(
    tenant_id="<azure-ad-tenant-id>",
    client_id="<client-application-id>",
    client_secret="<client-application-secret>")
client = CosmosClient("<account-endpoint>", aad_credentials)

驗證 REST API 上的要求

在建構 REST API 授權標頭時,將類型參數設定為 Microsoft Entra ID,並將雜湊簽章 (sig) 設定為 OAuth 權杖,如下列範例所示:

type=aad&ver=1.0&sig=<token-from-oauth>

使用資料總管

注意

Azure 入口網站中公開的資料總管尚不支援 Azure Cosmos DB 角色型存取控制。 若要在探索資料時使用您的 Microsoft Entra 身分識別,則必須改為使用 Azure Cosmos DB 總管

當您使用特定的 ?feature.enableAadDataPlane=true 查詢參數與登入來存取 Azure Cosmos DB 總管時,會使用下列邏輯存取您的資料:

  1. 代表已登入的身分識別嘗試擷取帳戶主要金鑰的要求。 若此要求成功,則會使用主要金鑰存取帳戶的資料。
  2. 若登入的身分識別不允許擷取帳戶的主要金鑰,則會直接使用此身分識別來驗證資料存取。 在此模式中,必須使用適當的角色定義來指派身分識別,以確保資料存取。

稽核資料要求

使用 Azure Cosmos DB 角色型存取控制時,會使用每個資料作業的身分識別與授權資訊來增強診斷記錄。 此增強功能可讓您執行詳細的稽核,並擷取傳送至 Azure Cosmos DB 帳戶之每個資料要求所使用的 Microsoft Entra 身分識別。

此額外資訊會在 DataPlaneRequests 記錄類別中流動,並由兩個額外的資料行所組成:

  • aadPrincipalId_g 顯示用於驗證要求的 Microsoft Entra 身分識別主體識別碼。
  • aadAppliedRoleAssignmentId_g 顯示授權要求時所接受的角色定義

強制將角色型存取控制當作唯一的驗證方法

在您想要強制用戶端單獨透過角色型存取控制連線至 Azure Cosmos DB 的情況下,您可以選擇停用帳戶的主要/次要金鑰。 當您這樣做時,將主動拒絕任何使用主要/次要金鑰或資源權杖的連入要求。

使用 Azure 資源管理員範本

使用 Azure Resource Manager 範本建立或更新 Azure Cosmos DB 帳戶時,請將 disableLocalAuth 屬性設定為 true

"resources": [
    {
        "type": " Microsoft.DocumentDB/databaseAccounts",
        "properties": {
            "disableLocalAuth": true,
            // ...
        },
        // ...
    },
    // ...
 ]

限制

  • 每個 Azure Cosmos DB 帳戶最多可建立 100 個角色定義與 2,000 個角色指派。
  • 您只能將角色定義指派給 Microsoft Entra 身分識別,其與 Azure Cosmos DB 帳戶屬於相同的 Microsoft Entra 租用戶。
  • 屬於超過 200 個群組的身分識別目前不支援 Microsoft Entra 群組解析。
  • Microsoft Entra 權杖目前會以標頭形式傳遞,並將每個個別要求傳送至 Azure Cosmos DB 服務,以增加整體承載大小。

常見問題集

本節包含角色型存取控制和 Azure Cosmos DB 的常見問題。

哪些 Azure Cosmos DB API 支援資料平面角色型存取控制?

到目前為止,僅支援 NoSQL API。

是否可以從 Azure 入口網站管理角色定義和角色指派?

尚未提供 Azure 入口網站的角色管理支援。

Azure Cosmos DB API for NoSQL 中的哪些 SDK 支援角色型存取控制?

目前支援 .NET V3Java V4JavaScript V3Python V4.3+ SDK。

Microsoft Entra 權杖在到期時是否會由 Azure Cosmos DB SDK 自動重新整理?

是。

使用角色型存取控制時,是否可以停用帳戶主要/次要金鑰?

是,請參閱強制將角色型存取控制當作唯一的驗證方法

下一步