基于角色的访问控制是指管理对 Azure 中资源的访问的方法。 此方法基于为特定身份分配角色,以管理他们对一个或多个资源的访问权限级别。 基于角色的访问控制提供了一个灵活的精细访问管理系统,可确保标识仅具有执行其任务所需的最低特权级别访问权限。
有关详细信息,请参阅 基于角色的访问控制。
先决条件
- 拥有有效订阅的 Azure 帐户。 创建账户。 
- 用于表的现有 Azure Cosmos DB 帐户 
- Microsoft Entra ID 中的一个或多个现有标识。 
可以使用本地 Azure CLI。
- 如果需要, 请安装 Azure CLI 以运行 CLI 引用命令。 
- 本地 Azure CLI,请了解如何安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行 Azure CLI。 有关详细信息,请参阅如何在 Docker 容器中运行 Azure CLI。 - 使用 az login 命令登录到 Azure CLI。 若要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅使用 Azure CLI 登录。 
- 出现提示时,请在首次使用时安装 Azure CLI 扩展。 有关扩展的详细信息,请参阅 将扩展与 Azure CLI 配合使用。 
- 运行az version命令,以查看已安装的版本和依赖库。 若要升级到最新版本,请运行az upgrade。 
 
- 如果选择在本地使用 Azure PowerShell:- 安装最新版本的 Az PowerShell 模块。
- 使用 Connect-AzAccount -Environment AzureChinaCloud cmdlet 连接到 Azure 帐户。
 
禁用基于密钥的身份验证
禁用基于密钥的授权可以防止在不使用更安全的 Microsoft Entra ID 身份验证方法的情况下使用您的帐户。 此过程是应在安全工作负荷中的新帐户上执行的步骤。 或者,对迁移到安全工作负荷模式的现有帐户执行此过程。
首先,对现有帐户禁用基于密钥的身份验证,以便应用程序需要使用 Microsoft Entra ID 身份验证。 请用 az resource update 修改现有帐户的 properties.disableLocalAuth。
az resource update \
    --resource-group "<name-of-existing-resource-group>" \
    --name "<name-of-existing-account>" \
    --resource-type "Microsoft.DocumentDB/databaseAccounts" \
    --set properties.disableLocalAuth=true
首先,创建禁用基于密钥的身份验证的新帐户,以便应用程序需要使用 Microsoft Entra 身份验证。
- 创建一个新的 Bicep 文件,以在禁用基于密钥的身份验证的情况下部署新帐户。 将文件命名为 deploy-new-account.bicep。 - metadata description = 'Deploys a new Azure Cosmos DB account with key-based auth disabled.' @description('Name of the Azure Cosmos DB account.') param name string = 'csms-${uniqueString(resourceGroup().id)}' @description('Primary location for the Azure Cosmos DB account.') param location string = resourceGroup().location resource account 'Microsoft.DocumentDB/databaseAccounts@2024-05-15' = { name: name location: location kind: 'GlobalDocumentDB' properties: { databaseAccountOfferType: 'Standard' locations: [ { locationName: location } ] disableLocalAuth: true } }
- 使用 - az deployment group create部署 Bicep 文件同时启用新帐户。- az deployment group create \ --resource-group "<name-of-existing-resource-group>" \ --template-file deploy-new-account.bicep
首先,对现有帐户禁用基于密钥的身份验证,以便应用程序需要使用 Microsoft Entra 身份验证。 分别使用 Get-AzResource 和 Set-AzResource 来读取和更新现有账号。
$parameters = @{
    ResourceGroupName = "<name-of-existing-resource-group>"
    ResourceName = "<name-of-existing-account>"
    ResourceType = "Microsoft.DocumentDB/databaseAccounts"
}
$resource = Get-AzResource @parameters
$resource.Properties.DisableLocalAuth = $true
$resource | Set-AzResource -Force
使用以下步骤创建禁用基于密钥的身份验证的新 Azure Cosmos DB for NoSQL 帐户,以便应用程序仅使用 Microsoft Entra 身份验证。
- 设置新的 Azure Cosmos DB for NoSQL 帐户时,导航到帐户创建过程 的安全 部分。 
- 然后,为基于密钥的身份验证选项选择“禁用”。   
重要
要修改 Azure Cosmos DB 帐户,需要至少具备 Microsoft.DocumentDb/databaseAccounts/*/write 权限的 Azure 角色。 有关详细信息,请参阅 Azure Cosmos DB 的权限。
验证是否已禁用基于密钥的身份验证
若要验证是否已禁用基于密钥的访问,请尝试使用 Azure SDK 通过资源所有者密码凭据(ROPC)连接到 Azure Cosmos DB for Table。 此尝试应失败。 如有必要,此处提供了常见编程语言的代码示例。
using Azure.Data.Tables;
using Azure.Core;
string connectionString = "AccountEndpoint=<table-endpoint>;AccountKey=<key>;";
TableServiceClient client = new(connectionString);
const { TableServiceClient } = require('@azure/data-tables');
const connectionString = 'AccountEndpoint=<table-endpoint>;AccountKey=<key>;';
const client = new TableServiceClient(connectionString);
import { TableServiceClient } from '@azure/data-tables';
let connectionString: string = 'AccountEndpoint=<table-endpoint>;AccountKey=<key>;';
const client: TableServiceClient = new TableServiceClient(connectionString);
from azure.data.tables import TableServiceClient
connection_string = "AccountEndpoint=<table-endpoint>;AccountKey=<key>;"
client = TableServiceClient(endpoint, connection_string)
package main
import (
    "github.com/Azure/azure-sdk-for-go/sdk/data/aztables"
)
const connectionString = "AccountEndpoint=<table-endpoint>;AccountKey=<key>;"
func main() {
  client, _ := aztables.NewServiceClientFromConnectionString(connectionString, nil)
}
import com.azure.data.tables.TableServiceClient;
import com.azure.data.tables.TableServiceClientBuilder;
public class Table{
    public static void main(String[] args){
        TableServiceClient tableServiceClient = new TableServiceClientBuilder()
            .connectionString("AccountEndpoint=<table-endpoint>;AccountKey=<key>;")
            .buildClient();
    }
}
授予控制平面基于角色的访问控制
控制平面访问是指无需管理数据即可管理 Azure 服务的资源。 例如,Azure Cosmos DB 控制平面访问可能包括:
- 读取所有帐户和资源元数据
- 读取和重新生成帐户密钥和连接字符串
- 执行帐户备份和还原
- 启动和跟踪数据传输作业
- 管理数据库和容器
- 修改帐户属性
重要
在 Azure Cosmos DB 中,您需要控制平面访问权限来管理本地数据平面基于角色的访问控制定义和分配。 由于 Azure Cosmos DB 的数据平面角色为基础的访问控制机制是原生的,因此需要控制平面访问来创建定义和分配,并将这些定义和分配作为资源存储在 Azure Cosmos DB 帐户中。
首先,必须准备一个角色定义,其中包含用于授予访问权限以管理 Azure Cosmos DB 中的帐户资源的权限的列表 actions 。 在本指南中,您将设置内置和自定义角色。 然后,将新定义的角色分配给身份,以确保你的应用程序可以访问 Azure Cosmos DB 中的资源。
- 使用 - az role definition list列出与 Azure Cosmos DB 帐户关联的所有角色定义。- az role definition list \ --name "Cosmos DB Operator"
- 查看输出并找到名为 Cosmos DB 运算符的角色定义。 输出包含属性中 - id角色定义的唯一标识符。 记下此值,因为本指南后面的工作分配步骤需要使用此值。- [ { "assignableScopes": [ "/" ], "description": "Lets you manage Azure Cosmos DB accounts, but not access data in them. Prevents access to account keys and connection strings.", "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/providers/Microsoft.Authorization/roleDefinitions/230815da-be43-4aae-9cb4-875f7bd000aa", "name": "230815da-be43-4aae-9cb4-875f7bd000aa", "permissions": [ { "actions": [ "Microsoft.DocumentDb/databaseAccounts/*", "Microsoft.Insights/alertRules/*", "Microsoft.Authorization/*/read", "Microsoft.ResourceHealth/availabilityStatuses/read", "Microsoft.Resources/deployments/*", "Microsoft.Resources/subscriptions/resourceGroups/read", "Microsoft.Support/*", "Microsoft.Network/virtualNetworks/subnets/joinViaServiceEndpoint/action" ], "condition": null, "conditionVersion": null, "dataActions": [], "notActions": [ "Microsoft.DocumentDB/databaseAccounts/dataTransferJobs/*", "Microsoft.DocumentDB/databaseAccounts/readonlyKeys/*", "Microsoft.DocumentDB/databaseAccounts/regenerateKey/*", "Microsoft.DocumentDB/databaseAccounts/listKeys/*", "Microsoft.DocumentDB/databaseAccounts/listConnectionStrings/*", "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions/write", "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions/delete", "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments/write", "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments/delete", "Microsoft.DocumentDB/databaseAccounts/mongodbRoleDefinitions/write", "Microsoft.DocumentDB/databaseAccounts/mongodbRoleDefinitions/delete", "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/write", "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/delete" ], "notDataActions": [] } ], "roleName": "Cosmos DB Operator", "roleType": "BuiltInRole", "type": "Microsoft.Authorization/roleDefinitions", } ]- 注释 - 在此示例中,该值 - id为- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/providers/Microsoft.Authorization/roleDefinitions/230815da-be43-4aae-9cb4-875f7bd000aa. 此示例使用虚构数据,标识符与此示例不同。 但是,标识符(- 230815da-be43-4aae-9cb4-875f7bd000aa)在 Azure 中的所有角色定义中全局唯一。
- 使用 - az group show来获取当前资源组的元数据。- az group show \ --name "<name-of-existing-resource-group>"
- 观察上一命令的输出。 记录此资源组的属性 - id值,因为下一步需要使用此属性。- { "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example", "location": "chinanorth3", "name": "msdocs-identity-example", "type": "Microsoft.Resources/resourceGroups" }- 注释 - 在此示例中,该值 - id为- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example. 此示例使用虚构数据,标识符与此示例不同。 此字符串是输出的截断示例。
- 创建名为 role-definition.json的新 JSON 文件。 在文件中,创建此资源定义,指定此处列出的值。 在 - AssignableScopes列表中,添加上一步中记录的资源组的- id属性。- { "Name": "Azure Cosmos DB Control Plane Owner", "IsCustom": true, "Description": "Can perform all control plane actions for an Azure Cosmos DB account.", "Actions": [ "Microsoft.DocumentDb/*" ], "AssignableScopes": [ "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example" ] }- 注释 - 此示例使用 - /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example上一步中记录的值。 实际资源标识符可能有所不同。
- 使用 - az role definition create. 创建一个新的角色定义。 使用 role-definition.json 文件作为- --role-definition参数的输入。- az role definition create \ --role-definition role-definition.json
- 查看定义创建命令的输出。 输出包含属性中 - id角色定义的唯一标识符。 记下此值,因为本指南后面的工作分配步骤需要使用此值。- { "assignableScopes": [ "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example" ], "description": "Can perform all control plane actions for an Azure Cosmos DB account.", "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1", "name": "e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5", "permissions": [ { "actions": [ "Microsoft.DocumentDb/*" ] } ], "roleName": "Azure Cosmos DB Control Plane Owner", "roleType": "CustomRole" }- 注释 - 在此示例中,该值 - id为- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1. 此示例使用虚构数据,标识符与此示例不同。 此示例是部署中输出的典型 JSON 的子集,为清楚起见。
- 使用 - az group show再次获取当前资源组的元数据。- az group show \ --name "<name-of-existing-resource-group>"
- 观察上一命令的输出。 记录此资源组的属性 - id值,因为下一步需要使用此属性。- { "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example", "location": "westus", "name": "msdocs-identity-example", "type": "Microsoft.Resources/resourceGroups" }- 注释 - 在此示例中,该值 - id为- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example. 此示例使用虚构数据,标识符与此示例不同。 此字符串是输出的截断示例。
- 使用 - az role assignment create分配新角色。 使用资源组的标识符作为- --scope参数,角色的标识符作为- -role参数,您的标识的唯一标识符作为- --assignee参数。- az role assignment create \ --assignee "<your-principal-identifier>" \ --role "subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1" \ --scope "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example"- 注释 - 在这个示例命令中, - scope被设置为上一个步骤中示例的虚构示例- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example。 资源组的标识符与此示例不同。- role也被设置为虚构的- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1。 同样,角色标识符将不同。
- 观察命令的输出。 输出中包含分配的唯一标识符在 - id属性中。- { "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleAssignments/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1", "name": "ffffffff-5555-6666-7777-aaaaaaaaaaaa", "principalId": "aaaaaaaa-bbbb-cccc-1111-222222222222", "resourceGroup": "msdocs-identity-example", "roleDefinitionId": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1", "scope": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example", "type": "Microsoft.Authorization/roleAssignments" }- 注释 - 在此示例中,该 - id属性是- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleAssignments/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1,另一个虚构示例。
- 重复这些步骤,从您希望使用的任何其他身份授予帐户访问权限。 - 小窍门 - 可以根据需要为任意数量身份重复这些步骤。 通常,这些步骤至少重复一次,以允许开发人员使用人工标识访问帐户,并允许应用程序使用托管标识访问数据。 
- 使用 - az role definition list列出与 Azure Cosmos DB 帐户关联的所有角色定义。- az role definition list \ --name "Cosmos DB Operator"
- 查看输出并找到名为 Cosmos DB 运算符的角色定义。 输出包含属性中 - id角色定义的唯一标识符。 记下此值,因为本指南后面的工作分配步骤需要使用此值。- [ { "assignableScopes": [ "/" ], "description": "Lets you manage Azure Cosmos DB accounts, but not access data in them. Prevents access to account keys and connection strings.", "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/providers/Microsoft.Authorization/roleDefinitions/230815da-be43-4aae-9cb4-875f7bd000aa", "name": "230815da-be43-4aae-9cb4-875f7bd000aa", "permissions": [ { "actions": [ "Microsoft.DocumentDb/databaseAccounts/*", "Microsoft.Insights/alertRules/*", "Microsoft.Authorization/*/read", "Microsoft.ResourceHealth/availabilityStatuses/read", "Microsoft.Resources/deployments/*", "Microsoft.Resources/subscriptions/resourceGroups/read", "Microsoft.Support/*", "Microsoft.Network/virtualNetworks/subnets/joinViaServiceEndpoint/action" ], "condition": null, "conditionVersion": null, "dataActions": [], "notActions": [ "Microsoft.DocumentDB/databaseAccounts/dataTransferJobs/*", "Microsoft.DocumentDB/databaseAccounts/readonlyKeys/*", "Microsoft.DocumentDB/databaseAccounts/regenerateKey/*", "Microsoft.DocumentDB/databaseAccounts/listKeys/*", "Microsoft.DocumentDB/databaseAccounts/listConnectionStrings/*", "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions/write", "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions/delete", "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments/write", "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments/delete", "Microsoft.DocumentDB/databaseAccounts/mongodbRoleDefinitions/write", "Microsoft.DocumentDB/databaseAccounts/mongodbRoleDefinitions/delete", "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/write", "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/delete" ], "notDataActions": [] } ], "roleName": "Cosmos DB Operator", "roleType": "BuiltInRole", "type": "Microsoft.Authorization/roleDefinitions", } ]- 注释 - 在此示例中,该值 - id为- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/providers/Microsoft.Authorization/roleDefinitions/230815da-be43-4aae-9cb4-875f7bd000aa. 此示例使用虚构数据,标识符与此示例不同。 但是,标识符(- 230815da-be43-4aae-9cb4-875f7bd000aa)在 Azure 中的所有角色定义中全局唯一。
- 创建新的 Bicep 文件以定义角色定义。 将文件 control-plane-role-definition.bicep 命名。 将以下项 - actions添加到定义:- Description - Microsoft.DocumentDb/*- 启用所有可能的作。 - metadata description = 'Create RBAC definition for control plane access to Azure Cosmos DB.' @description('Name of the role definition.') param roleDefinitionName string = 'Azure Cosmos DB Control Plane Owner' @description('Description of the role definition.') param roleDefinitionDescription string = 'Can perform all control plane actions for an Azure Cosmos DB account.' resource definition 'Microsoft.Authorization/roleDefinitions@2022-04-01' = { name: guid(subscription().id, resourceGroup().id, roleDefinitionName) scope: resourceGroup() properties: { roleName: roleDefinitionName description: roleDefinitionDescription type: 'CustomRole' permissions: [ { actions: [ 'Microsoft.DocumentDb/*' ] } ] assignableScopes: [ resourceGroup().id ] } } output definitionId string = definition.id
- 使用 - az deployment group create部署 Bicep 模板。 指定 Bicep 模板和 Azure 资源组的名称。- az deployment group create \ --resource-group "<name-of-existing-resource-group>" \ --template-file control-plane-role-definition.bicep
- 查看部署的输出。 输出包含属性中 - properties.outputs.definitionId.value角色定义的唯一标识符。 记下此值,因为本指南后面的工作分配步骤需要使用此值。- { "properties": { "outputs": { "definitionId": { "type": "String", "value": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1" } } } }- 注释 - 在此示例中,该值 - id为- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1. 此示例使用虚构数据,标识符与此示例不同。 此示例是部署中输出的典型 JSON 的子集,为清楚起见。
- 创建新的 Bicep 文件以定义角色分配。 将文件命名为 control-plane-role-assignment.bicep。 - metadata description = 'Assign RBAC role for control plane access to Azure Cosmos DB.' @description('Id of the role definition to assign to the targeted principal in the context of the account.') param roleDefinitionId string @description('Id of the identity/principal to assign this role in the context of the account.') param identityId string resource assignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(subscription().id, resourceGroup().id, roleDefinitionId, identityId) scope: resourceGroup() properties: { roleDefinitionId: roleDefinitionId principalId: identityId } }
- 创建名为 control-plane-role-assignment 的新 Bicep 参数文件。 - bicepparam在此参数文件中。将以前记录的角色定义标识符分配给参数- roleDefinitionId,将您身份的唯一标识符分配给参数- identityId。- using './control-plane-role-assignment.bicep' param roleDefinitionId = '<id-of-new-role-definition>' param identityId = '<id-of-existing-identity>'
- 使用 - az deployment group create部署此 Bicep 模板。- az deployment group create \ --resource-group "<name-of-existing-resource-group>" \ --parameters control-plane-role-assignment.bicepparam \ --template-file control-plane-role-assignment.bicep
- 重复这些步骤,从您希望使用的任何其他身份授予帐户访问权限。 - 小窍门 - 可以根据需要为任意数量身份重复这些步骤。 通常,这些步骤至少重复一次,以允许开发人员使用人工标识访问帐户,并允许应用程序使用托管标识访问数据。 
- 登录到 Azure 门户 (https://portal.azure.cn)。 
- 在全局搜索栏中输入 资源组 。 
- 在 “服务”中,选择 “资源组”。   
- 在“ 资源组 ”窗格中,选择现有的资源组。   - 注释 - 此示例屏幕截图包括 - msdocs-identity-example资源组。 实际的资源组名称可能不同。
- 在资源组的窗格中,在服务菜单中选择 访问控制(IAM )。   
- 在 “访问控制”(IAM) 窗格中,选择“ 角色”。   
- 在 “角色 ”部分中,使用搜索短语 Cosmos DB 并找到 Cosmos DB 操作员 角色定义。 然后,选择与该定义关联的 “视图 ”选项。   
- 在 Cosmos DB 操作员 角色定义对话框中,查看分配给此角色定义的一部分的操作。   
- 关闭 Cosmos DB 操作员 角色定义对话框。 
- 返回 “访问控制”(IAM) 窗格,选择“ 添加”。 然后选择 “添加自定义角色”。   
- 在 “基本信息 ”窗格中,配置以下选项,然后选择“ 下一步” : - 价值 - 自定义角色名称 - Azure Cosmos DB Control Plane Owner- 说明 - Can perform all control plane actions for an Azure Cosmos DB account.- 基线权限 - 从头开始   
- 在“ 权限 ”窗格中,选择“ 添加权限”。 然后,在权限对话框中搜索 - DocumentDB。 最后,选择 Microsoft.DocumentDB 选项。    
- 在“权限”对话框中,为 选择所有 - Microsoft.DocumentDB。 然后选择 “添加 ”以返回到“权限 ”窗格。  
- 返回“ 权限 ”窗格,观察权限列表。 然后选择 “查看 + 创建”。   
- 在 “审阅 + 创建 ”窗格中,查看新角色定义的指定选项。 最后,选择“ 创建”。   
- 等待门户完成角色定义创建。 
- 在 “访问控制”(IAM) 窗格中,选择“ 添加 ”,然后选择 “添加角色分配”。   
- 在 “角色 ”窗格中,搜索 - Azure Cosmos DB并选择本指南前面创建的 Azure Cosmos DB 控制平面所有者 角色。 然后选择下一步。  - 小窍门 - 可以选择筛选角色列表,以仅包含自定义角色。 
- 在“ 成员 ”窗格中,选择“ 选择成员 ”选项。 在成员对话框中,选择要为 Azure Cosmos DB 帐户授予此级别访问权限的标识,然后使用 “选择” 选项确认选择。     - 注释 - 此屏幕截图演示了一个名为 “Kai Carter” 和主体 - kai@adventure-works.com的示例用户。
- 返回“ 成员 ”窗格,查看所选成员[s],然后选择“ 审阅 + 分配”。   
- 在 “审阅 + 分配 ”窗格中,查看新角色分配的指定选项。 最后,选择“ 审阅 + 分配”。   
- 等待门户完成创建角色分配。 
- 用于 - Get-AzRoleDefinition列出与 Azure Cosmos DB 帐户关联的所有角色定义。- $parameters = @{ Name = "Cosmos DB Operator" } Get-AzRoleDefinition @parameters
- 查看输出并找到名为 Cosmos DB 内置数据参与者的角色定义。 输出包含属性中 - Id角色定义的唯一标识符。 记下此值,因为本指南后面的工作分配步骤需要使用此值。- Name : Cosmos DB Operator Id : 230815da-be43-4aae-9cb4-875f7bd000aa IsCustom : False Description : Lets you manage Azure Cosmos DB accounts, but not access data in them. Prevents access to account keys and connection strings. Actions : {Microsoft.DocumentDb/databaseAccounts/*, Microsoft.Insights/alertRules/*, Microsoft.Authorization/*/read, Microsoft.ResourceHealth/availabilityStatuses/read…} NotActions : {Microsoft.DocumentDB/databaseAccounts/dataTransferJobs/*, Microsoft.DocumentDB/databaseAccounts/readonlyKeys/*, Microsoft.DocumentDB/databaseAccounts/regenerateKey/*, Microsoft.DocumentDB/databaseAccounts/listKeys/*…} DataActions : {} NotDataActions : {} AssignableScopes : {/}- 注释 - 在此示例中,该值 - Id为- 230815da-be43-4aae-9cb4-875f7bd000aa. 该标识符在 Azure 中的所有角色定义中全局唯一。
- 使用 - Get-AzResourceGroup来获取当前资源组的元数据。- $parameters = @{ Name = "<name-of-existing-resource-group>" } Get-AzResourceGroup @parameters
- 观察上一命令的输出。 记录此资源组的属性 - ResourceId值,因为下一步需要使用此属性。- ResourceGroupName : msdocs-identity-example Location : westus ProvisioningState : Succeeded ResourceId : /subscriptions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1/resourcegroups/msdocs-identity-example- 注释 - 在此示例中,该值 - ResourceId为- /subscriptions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1/resourcegroups/msdocs-identity-example. 此示例使用虚构数据,标识符与此示例不同。 此字符串是典型输出的截断示例。
- 首先,导入 - Az.Resources模块。 然后,创建新- Microsoft.Azure.Commands.Resources.Models.Authorization.PSRoleDefinition对象。 在对象中,创建此资源定义,指定此处列出的值。 在- AssignableScopes列表中,添加上一步中记录的资源组的- ResourceId属性。 最后,使用角色定义对象作为- -Role的- New-AzRoleDefinition参数输入。- Import-Module Az.Resources $parameters = @{ TypeName = "Microsoft.Azure.Commands.Resources.Models.Authorization.PSRoleDefinition" Property = @{ Name = "Azure Cosmos DB Control Plane Owner" Description = "Can perform all control plane actions for an Azure Cosmos DB account." IsCustom = $true Actions = @( "Microsoft.DocumentDb/*" ) AssignableScopes = @( "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example" ) } } $role = New-Object @parameters New-AzRoleDefinition -Role $role- 注释 - 此示例使用 - /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example上一步中记录的值。 实际资源标识符可能有所不同。
- 查看定义创建命令的输出。 输出包含属性中 - Name角色定义的唯一标识符。 记下此值,因为本指南后面的工作分配步骤需要使用此值。- Name : Azure Cosmos DB Control Plane Owner Id : e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5 IsCustom : True Description : Can perform all control plane actions for an Azure Cosmos DB account. Actions : {Microsoft.DocumentDb/*} AssignableScopes : {/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example}- 注释 - 在此示例中,该值 - Name为- Azure Cosmos DB Control Plane Owner. 此示例是部署的典型输出的子集,以便清楚起见。
- 使用 - New-AzRoleAssignment分配新角色。 对于- RoleDefinitionName参数使用角色名称,而对于- ObjectId参数则使用您的标识唯一标识符。- $parameters = @{ ResourceGroupName = "<name-of-existing-resource-group>" ObjectId = "<your-principal-identifier>" RoleDefinitionName = "Azure Cosmos DB Control Plane Owner" } New-AzRoleAssignment @parameters
- 观察命令的输出。 输出中包含分配的唯一标识符在 - RoleAssignmentId属性中。- RoleAssignmentName : ffffffff-5555-6666-7777-aaaaaaaaaaaa RoleAssignmentId : /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleAssignments/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1 Scope : /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example DisplayName : Kai Carter SignInName : <kai@adventure-works.com> RoleDefinitionName : Azure Cosmos DB Control Plane Owner RoleDefinitionId : e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5- 注释 - 在此示例中,该 - RoleAssignmentId属性是- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleAssignments/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1,另一个虚构示例。 此示例是部署的典型输出的子集,以便清楚起见。
- 重复这些步骤,从您希望使用的任何其他身份授予帐户访问权限。 - 小窍门 - 可以根据需要为任意数量身份重复这些步骤。 通常,这些步骤至少重复一次,以允许开发人员使用人工标识访问帐户,并允许应用程序使用托管标识访问数据。 
重要
分配角色定义要求你已拥有要授予基于角色的访问控制权限的任何标识的唯一标识符。
在代码中验证基于角色的控制平面访问
验证是否已使用应用程序代码和 Azure 管理 SDK 正确授予访问权限。
using Azure.Identity;
using Azure.ResourceManager;
DefaultAzureCredential credential = new();
ArmClient client = new(credential);
const { CosmosDBManagementClient } = require('@azure/arm-cosmosdb');
const { DefaultAzureCredential } = require('@azure/identity');
const subscriptionId = "<subscription-id>";
const credential = new DefaultAzureCredential();
const client = new CosmosDBManagementClient(credential, subscriptionId);
import { CosmosDBManagementClient } from '@azure/arm-cosmosdb';
import { TokenCredential, DefaultAzureCredential } from '@azure/identity';
let subscriptionId: string = "<subscription-id>";
let credential: TokenCredential = new DefaultAzureCredential();
const client: CosmosDBManagementClient = new CosmosDBManagementClient(credential, subscriptionId);
from azure.mgmt.cosmosdb import CosmosDBManagementClient
from azure.identity import DefaultAzureCredential
subscription_id = "<subscription-id>"
credential = DefaultAzureCredential()
client = CosmosDBManagementClient(credential=credential, subscription=subscription_id)
package main
import (
    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
    "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/cosmos/armcosmos"
)
const subscriptionId = "<subscription-id>"
func main() {
    credential, _ := azidentity.NewDefaultAzureCredential(nil)
    
    client, _ := armcosmos.NewDatabaseClient(subscriptionId, credential, nil)
}
package com.example;
import com.azure.core.management.profile.AzureProfile;
import com.azure.core.management.AzureEnvironment;
import com.azure.identity.DefaultAzureCredential;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.resourcemanager.cosmos.CosmosManager;
public class CosmosDB {
    public static void main(String[] args) {
        AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE);
        DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
          .build();
        CosmosManager manager = CosmosManager.authenticate(credential, profile);
    }
}
授予数据平面基于角色的访问控制
数据平面访问是指能够在 Azure 服务中读取和写入数据,而无需管理帐户中的资源。 例如,Azure Cosmos DB 数据平面访问可能包括:
- 读取一些帐户和资源元数据
- 创建、读取、更新、修补和删除项目
- 执行表查询
- 从容器的更改源读取
- 执行存储过程
- 管理冲突源中的冲突
首先,必须准备一个角色定义,其中包含用于授予对 Azure Cosmos DB for Table 中读取、查询和管理数据的访问权限的列表 dataActions 。 在本指南中,您将设置内置和自定义角色。 然后,将新定义的角色(们)分配给身份,以便应用程序可以访问 Azure Cosmos DB for Table 中的数据。
- 首先,获取现有 Azure Cosmos DB for Table 帐户 - az cosmsodb show的资源标识符,并将其存储在变量中。- resourceId=$( \ az cosmosdb show \ --resource-group "<name-of-existing-resource-group>" \ --name "<name-of-existing-table-account>" \ --query "id" \ --output tsv \ ) az rest \ --method "GET" \ --url $resourceId/tableRoleDefinitions?api-version=2023-04-15
- 然后,使用 - az rest列出与 Azure Cosmos DB 表帐户关联的所有角色定义。 最后,查看输出并找到名为 Cosmos DB 内置数据参与者的角色定义。 输出包含属性中- id角色定义的唯一标识符。 记下此值,因为本指南后面的工作分配步骤需要使用此值。- [ ..., { "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table/tableRoleDefinitions/00000000-0000-0000-0000-000000000002", "name": "00000000-0000-0000-0000-000000000002", "properties": { "assignableScopes": [ "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table" ], "permissions": [ { "dataActions": [ "Microsoft.DocumentDB/databaseAccounts/readMetadata", "Microsoft.DocumentDB/databaseAccounts/tables/*", "Microsoft.DocumentDB/databaseAccounts/tables/containers/entities/*" ], "notDataActions": [] } ], "roleName": "Cosmos DB Built-in Data Contributor", "type": "BuiltInRole" }, "type": "Microsoft.DocumentDB/databaseAccounts/tableRoleDefinitions" } ... ]- 注释 - 在此示例中,该值 - id为- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table/tableRoleDefinitions/00000000-0000-0000-0000-000000000002. 此示例使用虚构数据,标识符与此示例不同。 此示例输出被截断。
- 创建名为 role-definition.json的新 JSON 文件。 在此文件中,创建一个资源定义,指定此处列出的数据操作: - Description - Microsoft.DocumentDB/databaseAccounts/readMetadata- 可以读取帐户级元数据 - Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*- 可以执行任何容器级数据作业 - Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*- 可以对带有容器的项执行任何操作 - { "properties": { "roleName": "Azure Cosmos DB for Table Data Plane Owner", "type": "CustomRole", "assignableScopes": [ "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/sidandrews-rbac/providers/Microsoft.DocumentDB/databaseAccounts/sidandrews-rbac-table/" ], "permissions": [ { "dataActions": [ "Microsoft.DocumentDB/databaseAccounts/readMetadata", "Microsoft.DocumentDB/databaseAccounts/tables/*", "Microsoft.DocumentDB/databaseAccounts/tables/containers/entities/*" ] } ] } }
- 现在,使用 - az cosmosdb show和- az rest一起创建或更新角色定义来发出 HTTP- PUT请求。 作为此请求的一部分,请为角色定义指定唯一的 GUID。- resourceId=$( \ az cosmosdb show \ --resource-group "<name-of-existing-resource-group>" \ --name "<name-of-existing-table-account>" \ --query "id" \ --output tsv \ ) az rest \ --method "PUT" \ --url $resourceId/tableRoleDefinitions/d3d3d3d3-eeee-ffff-aaaa-b4b4b4b4b4b4?api-version=2023-04-15 \ --body @role-definition.json- 注释 - 在此示例中,指定的唯一 GUID 为 - d3d3d3d3-eeee-ffff-aaaa-b4b4b4b4b4b4。 可以为自己的角色定义指定任何唯一的 GUID。
- 现在输出应显示请求已排队。 现在,等待已排队的角色定义部署完成。 此任务可能需要几分钟时间。 - { "status": "Enqueued" }
- 使用 - az rest再次检查角色定义列表。- resourceId=$( \ az cosmosdb show \ --resource-group "<name-of-existing-resource-group>" \ --name "<name-of-existing-table-account>" \ --query "id" \ --output tsv \ ) az rest \ --method "GET" \ --url $resourceId/tableRoleDefinitions?api-version=2023-04-15
- 使用 - az cosmosdb show获取当前帐户的唯一标识符。- az cosmosdb show \ --resource-group "<name-of-existing-resource-group>" \ --name "<name-of-existing-resource-group>" \ --query "{id:id}"
- 观察上一命令的输出。 记录此帐户的属性 - id值,因为下一步需要使用此属性。- { "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table" }- 注释 - 在此示例中,该值 - id为- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table. 此示例使用虚构数据,标识符与此示例不同。
- 创建名为 role-assignment.json的新 JSON 文件。 在 JSON 文件中,添加您的身份的唯一标识符以及帐户资源的唯一标识符。 - { "properties": { "roleDefinitionId": "<account-resource-id>/tableRoleDefinitions/d3d3d3d3-eeee-ffff-aaaa-b4b4b4b4b4b4", "scope": "<account-resource-id>", "principalId": "<id-of-existing-identity>" } }- 注释 - 在此示例中,指定的唯一 GUID 为 - d3d3d3d3-eeee-ffff-aaaa-b4b4b4b4b4b4。 可以使用以前用于自己的角色定义的唯一 GUID。- 小窍门 - 在 Azure Cosmos DB 的基于角色的访问控制的本机实现中, 范围 是指想要应用权限的帐户中的资源的粒度。 在最高级别,可以使用最大作用域将数据平面基于角色的访问控制分配限定到整个帐户。 此范围包括帐户中的所有数据库和容器: - /subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/- 或者,可以将数据平面角色分配的范围限定为特定的数据库: - /subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/dbs/<database-name>- 最后,可以将分配范围限定为单个容器,这是最精细的范围: - /subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/dbs/<database-name>/colls/<container-name>- 在许多情况下,可以使用相对范围而不是完全限定的范围。 例如,可以使用此相对范围从 Azure CLI 命令向特定数据库和容器授予基于角色的数据平面访问控制权限: - /dbs/<database-name>/colls/<container-name>- 还可以使用相对范围授予对所有数据库和容器的通用访问权限: - /
- 现在,使用 - az cosmosdb show和- az rest一起创建或更新角色分配来发出 HTTP- PUT请求。 作为此请求的一部分,请为您的角色分配指定一个唯一的 GUID。- resourceId=$( \ az cosmosdb show \ --resource-group "<name-of-existing-resource-group>" \ --name "<name-of-existing-table-account>" \ --query "id" \ --output tsv \ ) az rest \ --method "PUT" \ --url $resourceId/tableRoleAssignments/e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5?api-version=2023-04-15 \ --body @role-assignment.json- 注释 - 在此示例中,指定的唯一 GUID 为 - e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5。 您可以为自己的角色分配任何唯一的 GUID。
- 首先,获取现有 Azure Cosmos DB for Table 帐户 - az cosmsodb show的资源标识符,并将其存储在变量中。- resourceId=$( \ az cosmosdb show \ --resource-group "<name-of-existing-resource-group>" \ --name "<name-of-existing-table-account>" \ --query "id" \ --output tsv \ ) az rest \ --method "GET" \ --url $resourceId/tableRoleDefinitions?api-version=2023-04-15
- 然后,使用 - az rest列出与 Azure Cosmos DB 表帐户关联的所有角色定义。 最后,查看输出并找到名为 Cosmos DB 内置数据参与者的角色定义。 输出包含属性中- id角色定义的唯一标识符。 记下此值,因为本指南后面的工作分配步骤需要使用此值。- [ ..., { "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table/tableRoleDefinitions/00000000-0000-0000-0000-000000000002", "name": "00000000-0000-0000-0000-000000000002", "properties": { "assignableScopes": [ "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table" ], "permissions": [ { "dataActions": [ "Microsoft.DocumentDB/databaseAccounts/readMetadata", "Microsoft.DocumentDB/databaseAccounts/tables/*", "Microsoft.DocumentDB/databaseAccounts/tables/containers/entities/*" ], "notDataActions": [] } ], "roleName": "Cosmos DB Built-in Data Contributor", "type": "BuiltInRole" }, "type": "Microsoft.DocumentDB/databaseAccounts/tableRoleDefinitions" } ... ]- 注释 - 在此示例中,该值 - id为- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table/tableRoleDefinitions/00000000-0000-0000-0000-000000000002. 此示例使用虚构数据,标识符与此示例不同。 此示例输出被截断。
- 创建新的 Bicep 文件以定义角色定义。 将文件 命名为 data-plane-role-definition.bicep。 将以下项 - dataActions添加到定义:- Description - Microsoft.DocumentDB/databaseAccounts/readMetadata- Microsoft.DocumentDB/databaseAccounts/tables/*- Microsoft.DocumentDB/databaseAccounts/tables/containers/entities/*- metadata description = 'Create RBAC definition for data plane access to Azure Cosmos DB for Table.' @description('Name of the Azure Cosmos DB for Table account.') param accountName string @description('Name of the role definition.') param roleDefinitionName string = 'API for Table Data Plane Owner' resource account 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' existing = { name: accountName } resource definition 'Microsoft.DocumentDB/databaseAccounts/tableRoleDefinitions@2023-04-15' = { name: guid('table-role-definition', account.id) parent: account properties: { roleName: roleDefinitionName type: 'CustomRole' assignableScopes: [ account.id ] permissions: [ { dataActions: [ 'Microsoft.DocumentDB/databaseAccounts/readMetadata' 'Microsoft.DocumentDB/databaseAccounts/tables/*' 'Microsoft.DocumentDB/databaseAccounts/tables/containers/entities/*' ] } ] } } output definitionId string = definition.id- 小窍门 - 在 Azure Cosmos DB 的基于角色的访问控制的本机实现中, 范围 是指想要应用权限的帐户中的资源的粒度。 在最高级别,可以使用最大作用域将数据平面基于角色的访问控制分配限定到整个帐户。 此范围包括帐户中的所有数据库和容器: - /subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/- 或者,可以将数据平面角色分配的范围限定为特定的数据库: - /subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/dbs/<database-name>- 最后,可以将分配范围限定为单个容器,这是最精细的范围: - /subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/dbs/<database-name>/colls/<container-name>- 在许多情况下,可以使用相对范围而不是完全限定的范围。 例如,可以使用此相对范围从 Azure CLI 命令向特定数据库和容器授予基于角色的数据平面访问控制权限: - /dbs/<database-name>/colls/<container-name>- 还可以使用相对范围授予对所有数据库和容器的通用访问权限: - /
- 创建名为 - data-plane-role-definition.bicepparam的新 Bicep 参数文件。 在此参数文件中,将现有 Azure Cosmos DB for Table 帐户的名称分配给该- accountName参数。- using './data-plane-role-definition.bicep' param accountName = '<name-of-existing-table-account>'
- 使用 - az deployment group create部署 Bicep 模板。 指定 Bicep 模板、参数文件和 Azure 资源组的名称。- az deployment group create \ --resource-group "<name-of-existing-resource-group>" \ --parameters data-plane-role-definition.bicepparam \ --template-file data-plane-role-definition.bicep
- 查看部署的输出。 输出包含属性中 - properties.outputs.definitionId.value角色定义的唯一标识符。 记下此值,因为本指南后面的工作分配步骤需要使用此值。- { "properties": { "outputs": { "definitionId": { "type": "String", "value": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table-account/tableRoleDefinitions/dddddddd-9999-0000-1111-eeeeeeeeeeee" } } } }- 注释 - 在此示例中,该值 - id为- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table-account/tableRoleDefinitions/dddddddd-9999-0000-1111-eeeeeeeeeeee. 此示例使用虚构数据,标识符与此示例不同。 此示例是部署中输出的典型 JSON 的子集,为清楚起见。
- 创建另一个 Bicep 文件来为标识分配角色。 将此文件命名 为 data-plane-role-assignment.bicep。 - metadata description = 'Assign RBAC role for data plane access to Azure Cosmos DB for Table.' @description('Name of the Azure Cosmos DB for Table account.') param accountName string @description('Id of the role definition to assign to the targeted principal in the context of the account.') param roleDefinitionId string @description('Id of the identity/principal to assign this role in the context of the account.') param identityId string resource account 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' existing = { name: accountName } resource assignment 'Microsoft.DocumentDB/databaseAccounts/tableRoleAssignments@2023-04-15' = { name: guid(roleDefinitionId, identityId, account.id) parent: account properties: { principalId: identityId roleDefinitionId: roleDefinitionId scope: account.id } } output id string = assignment.id
- 创建名为 - data-plane-role-assignment.bicepparam的新 Bicep 参数文件。 在此参数文件中,将现有的 Azure Cosmos DB for Table 帐户的名称分配给- accountName参数,将以前记录的角色定义标识符分配给- roleDefinitionId参数,并将身份的唯一标识符分配给- identityId参数。- using './data-plane-role-assignment.bicep' param accountName = '<name-of-existing-table-account>' param roleDefinitionId = '<id-of-new-role-definition>' param identityId = '<id-of-existing-identity>'
- 使用 - az deployment group create部署此 Bicep 模板。- az deployment group create \ --resource-group "<name-of-existing-resource-group>" \ --parameters data-plane-role-assignment.bicepparam \ --template-file data-plane-role-assignment.bicep
- 重复这些步骤,从您希望使用的任何其他身份授予帐户访问权限。 - 小窍门 - 可以根据需要为任意数量身份重复这些步骤。 通常,这些步骤至少重复一次,以允许开发人员使用其人工标识访问帐户,并允许应用程序使用托管标识访问数据。 
- 用于 - Get-AzCosmosDBAccount获取现有 Azure Cosmos DB for Table 帐户的资源标识符,并将其存储在变量中。- $parameters = @{ ResourceGroupName = "<name-of-existing-resource-group>" Name = "<name-of-existing-table-account>" } $resourceId = ( Get-AzCosmosDBAccount @parameters | Select-Object -Property Id -First 1 ).Id $parameters = @{ Path = "$resourceId/tableRoleDefinitions?api-version=2023-04-15" Method = "GET" } Invoke-AzRestMethod @parameters
- 然后,用于 - Invoke-AzRestMethod列出与 Azure Cosmos DB for Table 帐户关联的所有角色定义。 查看输出并找到名为 Cosmos DB 内置数据参与者的角色定义。 输出包含属性中- Id角色定义的唯一标识符。 记下此值,因为本指南后面的工作分配步骤需要使用此值。- StatusCode : 200 Content : { "value": [ ..., { "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table/tableRoleDefinitions/00000000-0000-0000-0000-000000000002", "name": "00000000-0000-0000-0000-000000000002", "properties": { "assignableScopes": [ "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table" ], "permissions": [ { "dataActions": [ "Microsoft.DocumentDB/databaseAccounts/readMetadata", "Microsoft.DocumentDB/databaseAccounts/tables/*", "Microsoft.DocumentDB/databaseAccounts/tables/containers/entities/*" ], "notDataActions": [] } ], "roleName": "Cosmos DB Built-in Data Contributor", "type": "BuiltInRole" }, "type": "Microsoft.DocumentDB/databaseAccounts/tableRoleDefinitions" } ... ] }, ... ] }- 注释 - 在此示例中,该值 - Id为- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table/tableRoleDefinitions/00000000-0000-0000-0000-000000000002. 此示例使用虚构数据,标识符与此示例不同。 此示例输出被截断。
- 使用 - Get-AzCosmosDBAccount和- Invoke-AzRestMethod一起创建或更新角色定义来发出 HTTP- PUT请求。 此外,作为此请求的一部分,请为角色定义指定唯一的 GUID。 最后,创建一个资源定义有效负载,指定所列的数据操作:- Description - Microsoft.DocumentDB/databaseAccounts/readMetadata- 可以读取帐户级元数据 - Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*- 可以执行任何容器级数据作业 - Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*- 可以对带有容器的项执行任何操作 - $parameters = @{ ResourceGroupName = "<name-of-existing-resource-group>" Name = "<name-of-existing-table-account>" } $resourceId = ( Get-AzCosmosDBAccount @parameters | Select-Object -Property Id -First 1 ).Id $payload = @{ properties = @{ roleName = "Azure Cosmos DB for Table Data Plane Owner" type = "CustomRole" assignableScopes = @( "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/sidandrews-rbac/providers/Microsoft.DocumentDB/databaseAccounts/sidandrews-rbac-table/" ) permissions = @( @{ dataActions = @( "Microsoft.DocumentDB/databaseAccounts/readMetadata", "Microsoft.DocumentDB/databaseAccounts/tables/*", "Microsoft.DocumentDB/databaseAccounts/tables/containers/entities/*" ) } ) } } $parameters = @{ Path = "$resourceId/tableRoleDefinitions/d3d3d3d3-eeee-ffff-aaaa-b4b4b4b4b4b4?api-version=2023-04-15" Method = "PUT" Payload = $payload | ConvertTo-Json -Depth 4 } Invoke-AzRestMethod @parameters- 注释 - 在此示例中,指定的唯一 GUID 为 - d3d3d3d3-eeee-ffff-aaaa-b4b4b4b4b4b4。 可以为自己的角色定义指定任何唯一的 GUID。- 小窍门 - 在 Azure Cosmos DB 的基于角色的访问控制的本机实现中, 范围 是指想要应用权限的帐户中的资源的粒度。 在最高级别,可以使用最大作用域将数据平面基于角色的访问控制分配限定到整个帐户。 此范围包括帐户中的所有数据库和容器: - /subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/- 或者,可以将数据平面角色分配的范围限定为特定的数据库: - /subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/dbs/<database-name>- 最后,可以将分配范围限定为单个容器,这是最精细的范围: - /subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/dbs/<database-name>/colls/<container-name>- 在许多情况下,可以使用相对范围而不是完全限定的范围。 例如,可以使用此相对范围从 Azure CLI 命令向特定数据库和容器授予基于角色的数据平面访问控制权限: - /dbs/<database-name>/colls/<container-name>- 还可以使用相对范围授予对所有数据库和容器的通用访问权限: - /
- 输出应返回状态代码 为 200。 现在,等待已排队的角色定义部署完成。 此任务可能需要几分钟时间。 - StatusCode : 200 ...
- 使用 - Invoke-AzRestMethod再次检查角色定义列表。- $parameters = @{ ResourceGroupName = "<name-of-existing-resource-group>" Name = "<name-of-existing-table-account>" } $resourceId = ( Get-AzCosmosDBAccount @parameters | Select-Object -Property Id -First 1 ).Id $parameters = @{ Path = "$resourceId/tableRoleDefinitions?api-version=2023-04-15" Method = "GET" } Invoke-AzRestMethod @parameters
- 使用“Get-AzCosmosDBAccount”命令来获取当前帐户的唯一标识符。 - $parameters = @{ ResourceGroupName = "<name-of-existing-resource-group>" Name = "<name-of-existing-table-account>" } Get-AzCosmosDBAccount @parameters | Select -Property Id
- 观察上一命令的输出。 记录此帐户的属性 - Id值,因为下一步需要使用此属性。- Id -- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table- 注释 - 在此示例中,该值 - Id为- /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table. 此示例使用虚构数据,标识符与此示例不同。
- 现在,使用 - Get-AzCosmosDBAccount和- Invoke-AzRestMethod一起创建或更新角色分配来发出 HTTP- PUT请求。 作为此请求的一部分,请为您的角色分配指定一个唯一的 GUID。 最后,创建一个资源分配数据载荷,指定您的标识的唯一标识符。- $parameters = @{ ResourceGroupName = "<name-of-existing-resource-group>" Name = "<name-of-existing-table-account>" } $resourceId = ( Get-AzCosmosDBAccount @parameters | Select-Object -Property Id -First 1 ).Id $payload = @{ properties = @{ roleDefinitionId = "$resourceId/tableRoleDefinitions/00000000-0000-0000-0000-000000000002" scope = "$resourceId" principalId = "<id-of-existing-identity>" } } $parameters = @{ Path = "$resourceId/tableRoleAssignments/e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5?api-version=2023-04-15" Method = "PUT" Payload = $payload | ConvertTo-Json -Depth 2 } Invoke-AzRestMethod @parameters- 注释 - 在此示例中,指定的唯一 GUID 为 - e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5。 您可以为自己的角色分配任何唯一的 GUID。
警告
Azure 门户中不支持管理基于角色的数据平面访问控制。
在代码中验证基于角色的数据平面访问
验证是否已使用应用程序代码和 Azure SDK 正确授予访问权限。
using Azure.Identity;
using Azure.Data.Tables;
string endpoint = "<account-endpoint>";
DefaultAzureCredential credential = new();
TableServiceClient client = new(
    endpoint: new Uri(endpoint),
    tokenCredential: credential
);
TableClient table = client.GetTableClient(
    tableName: "<name-of-table>"
);
await table.GetEntityAsync<TableEntity>(
    partitionKey: "<partition-key>",
    rowKey: "<row-key>"
);
const { TableServiceClient, TableClient } = require('@azure/data-tables');
const { DefaultAzureCredential } = require('@azure/identity');
const endpoint = '<account-endpoint>';
let credential = new DefaultAzureCredential();
let client = new TableServiceClient(endpoint, credential);
let table = new TableClient(endpoint, "<table-name>", credential);
await table.getEntity("<partition-key>", "<row-key>");
import { TableServiceClient, TableClient } from '@azure/data-tables';
import { TokenCredential, DefaultAzureCredential } from '@azure/identity';
const endpoint: string = '<account-endpoint>';
let credential: TokenCredential = new DefaultAzureCredential();
let client: TableServiceClient = new TableServiceClient(endpoint, credential);
let table: TableClient = new TableClient(endpoint, "<table-name>", credential);
await table.getEntity("<partition-key>", "<row-key>");
from azure.data.tables import TableServiceClient
from azure.identity import DefaultAzureCredential
endpoint = "<account-endpoint>"
credential = DefaultAzureCredential()
client = TableServiceClient(endpoint, credential=credential)
table = client.get_table_client("<table-name>")
table.get_entity(
    row_key="<row-key>",
    partition_key="<partition-key>"
)
import (
    "context"
    
    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
    "github.com/Azure/azure-sdk-for-go/sdk/data/aztables"
)
const endpoint = "<account-endpoint>"
func main() {
    credential, _ := azidentity.NewDefaultAzureCredential(nil)
    client, _ := aztables.NewServiceClient(endpoint, credential, nil)
    table := client.NewClient("<table-name>")
    
    _, err := table.GetEntity(context.TODO(), "<partition-key>", "<row-key>", nil)
    if err != nil {
        panic(err)
    }
}
import com.azure.data.tables.TableClient;
import com.azure.data.tables.TableServiceClient;
import com.azure.data.tables.TableServiceClientBuilder;
import com.azure.identity.DefaultAzureCredential;
import com.azure.identity.DefaultAzureCredentialBuilder;
public class Table{
    public static void main(String[] args){
        DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
            .build();
        
        TableServiceClient client = new TableServiceClientBuilder()
            .endpoint("<table-endpoint>")
            .credential(credential)
            .buildClient();
        TableClient table = client
            .getTableClient("<table-name>");
        table.getEntity("<partition-key>", "<row-key>");
    }
}
