重要
你是否正在寻找一种数据库解决方案,以应对需要高扩展性、99.999% 可用性服务级别协议(SLA)、即时自动扩展和跨多个区域的自动故障转移的场景? 请考虑使用 Azure Cosmos DB for NoSQL。
基于角色的访问控制是指管理对 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
按照以下步骤为禁用基于密钥的身份验证的 NoSQL 帐户创建新的Azure Cosmos DB,以便应用程序仅使用Microsoft Entra身份验证。
为 NoSQL 帐户设置新的Azure Cosmos DB时,请转到帐户创建过程的 Security 部分。
对于 基于密钥的身份验证 选项,请选择“ 禁用”。
重要
要修改 Azure Cosmos DB 帐户,需要至少具备 Microsoft.DocumentDb/databaseAccounts/*/write 权限的 Azure 角色。 有关详细信息,请参阅 permissions for 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中管理帐户资源的访问权限。 在本文中,你将创建一个内置角色和一个自定义角色。 然后,将新定义的一个或多个角色分配给标识,以便应用程序能够访问 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。 将以下操作添加到定义:Action 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.bicepparam的新 Bicep 参数文件。 在此参数文件中,将以前记录的角色定义标识符分配给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 门户。
在全局搜索栏中输入 资源组 。
在 “服务”中,选择 “资源组”。
在“ 资源组 ”窗格中,选择现有的资源组。
此示例屏幕截图包括
msdocs-identity-example资源组。 实际的资源组名称可能不同。在资源组的窗格中,选择服务菜单上的 访问控制(IAM )。
在 “访问控制”(IAM) 窗格中,选择“ 角色”。
在 “角色 ”部分中,使用搜索短语 Cosmos DB 并找到 Cosmos DB 操作员 角色定义。 然后,选择与该定义关联的 “视图 ”选项。
在 Cosmos DB 操作员 角色定义对话框中,查看分配给此角色定义的一部分的操作。
关闭 Cosmos DB 操作员 角色定义对话框。
返回 “访问控制”(IAM) 窗格,选择“ 添加”。 然后选择 “添加自定义角色”。
在 “基本信息 ”窗格中,配置以下选项,然后选择“ 下一步”。
Option 价值 自定义角色名称 Azure Cosmos DB 控制平面负责人 说明 可对 Azure Cosmos DB 帐户执行所有控制平面操作。 基线权限 从头开始
在“ 权限 ”窗格中,选择“ 添加权限”。 然后,在“权限”对话框中搜索 DocumentDB。 最后,选择 Microsoft.DocumentDB 选项。
在权限对话框中,选择Microsoft.DocumentDB的所有操作。 然后选择“ 添加 ”以返回到 “权限 ”窗格。
返回“ 权限 ”窗格,观察权限列表。 然后选择 “查看 + 创建”。
在 “审阅 + 创建 ”窗格中,查看新角色定义的指定选项。 最后,选择“ 创建”。
等待门户完成角色定义创建。
在 “访问控制”(IAM) 窗格中,选择“ 添加添加>角色分配”。
在 Role 窗格中,搜索 Azure Cosmos DB,然后选择本文前面创建的Azure Cosmos DB控制平面所有者角色。 然后选择下一步。
可以选择筛选角色列表,以仅包含自定义角色。
在“ 成员 ”窗格中,选择“ 选择成员 ”选项。 在 Members 对话框中,选择要为 Azure Cosmos DB 帐户授予此级别的访问权限的标识。 然后使用 “选择” 选项确认你的选择。
此屏幕截图展示了一个示例用户,名为 Kai Carter,主体为
kai@adventure-works.com。返回“ 成员 ”窗格,查看所选成员,然后选择“ 审阅 + 分配”。
在 “审阅 + 分配 ”窗格中,查看新角色分配的指定选项。 最后,选择“ 审阅 + 分配”。
等待门户完成创建角色分配。
使用
Get-AzRoleDefinition列出与Azure Cosmos DB帐户关联的所有角色定义。$parameters = @{ Name = "Cosmos DB Operator" } Get-AzRoleDefinition @parameters查看输出并找到名为
Cosmos DB Built-in Data Contributor的角色定义。 输出包含属性中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一起创建或更新角色定义来发出 HTTPPUT请求。 作为此请求的一部分,请为角色定义指定唯一的 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一起创建或更新角色分配来发出 HTTPPUT请求。 作为此请求的一部分,请为您的角色分配指定一个唯一的 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/readMetadataMicrosoft.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一起创建或更新角色定义来发出 HTTPPUT请求。 此外,作为此请求的一部分,请为角色定义指定唯一的 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一起创建或更新角色分配来发出 HTTPPUT请求。 作为此请求的一部分,请为您的角色分配指定一个唯一的 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>");
}
}