基于角色的访问控制是指管理对 Azure 中资源的访问的方法。 此方法基于将特定标识分配角色,管理其对一个或多个资源的访问级别。 基于角色的访问控制提供了一个灵活的精细访问管理系统,以确保标识只有执行其任务所需的最低特权访问级别。
有关详细信息,请参阅基于角色的访问控制。
先决条件
- 使用一个拥有有效订阅的 Azure 帐户。 创建帐户。
- 对 Gremlin 帐户使用现有Azure Cosmos DB。
- 在Microsoft Entra ID中使用一个或多个现有标识。
如需在本地运行 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 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 部分。
对于 基于密钥的身份验证 选项,请选择“ 禁用”。
Important
要修改 Azure Cosmos DB 帐户,需要至少具备 Microsoft.DocumentDb/databaseAccounts/*/write 权限的 Azure 角色。 有关详细信息,请参阅 permissions for Azure Cosmos DB。
验证是否已禁用基于密钥的身份验证
若要验证是否已禁用基于密钥的访问,请使用Azure SDK通过资源所有者密码凭据连接到 Gremlin 的 Azure Cosmos DB。 此尝试应失败。 如有必要,此处提供了常见编程语言的代码示例。
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);
from azure.data.tables import TableServiceClient
connection_string = "AccountEndpoint=<table-endpoint>;AccountKey=<key>;"
client = TableServiceClient(endpoint, connection_string)
授予控制平面基于角色的访问控制
控制平面访问是指无需管理数据即可管理Azure服务资源。 访问Azure Cosmos DB控制平面的权限可能包括:
- 读取所有帐户和资源元数据。
- 读取和重新生成帐户密钥和连接字符串。
- 执行帐户备份和还原。
- 启动和跟踪数据传输作业。
- 管理数据库和容器。
- 修改帐户属性。
Important
在 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 )。
在 Access control (IAM) 窗格中,选择 Roles。
在 “角色 ”部分中,使用搜索短语 Cosmos DB 并找到 Cosmos DB 操作员 角色定义。 然后,选择与该定义关联的 “视图 ”选项。
在 Cosmos DB 操作员 角色定义对话框中,查看分配给此角色定义的一部分的操作。
关闭 Cosmos DB 操作员 角色定义对话框。
返回 “访问控制”(IAM) 窗格,选择“ 添加”。 然后选择 “添加自定义角色”。
在 “基本信息 ”窗格中,配置以下选项,然后选择“ 下一步”。
Option 价值 自定义角色名称 Azure Cosmos DB 控制平面负责人 Description 可对 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,这是另一个虚构的示例。 此示例是为了清晰起见而展示的典型部署输出的一个子集。对您想要使用的任何其他身份,重复执行这些步骤以授予其对该账户的访问权限。
您可以根据需要,对任意数量的身份重复这些步骤。 通常,这些步骤至少重复一次,以允许开发人员使用人工标识访问帐户,并允许应用程序使用托管标识访问数据。
Important
分配角色定义时,需要你事先知道要向其授予基于角色的访问控制权限的任何标识的唯一标识符。
在代码中验证基于角色的控制平面访问
使用应用程序代码和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 数据平面访问可能包括:
- 读取一些帐户和资源元数据。
- 创建、读取、更新、修补和删除项。
- 运行 Gremlin 查询。
- 从容器的更改馈送中读取。
- 运行存储过程。
- 管理冲突源中的冲突。
首先,必须使用数据操作列表准备角色定义,以授予对 Gremlin Azure Cosmos DB中读取、查询和管理数据的访问权限。 在本文中,你将准备一个内置角色和一个自定义角色。 然后,将新定义的角色分配给某个标识,以便应用程序可以访问 Azure Cosmos DB for Gremlin 中的数据。
使用
az cosmosdb gremlin role definition list列出与 Gremlin 帐户Azure Cosmos DB关联的所有角色定义。az cosmosdb gremlin role definition list \ --account-name <account-name> \ --resource-group <resource-group>查看输出并找到名为
Cosmos DB Built-in Data Contributor的角色定义。 输出包含属性中id角色定义的唯一标识符。 记录此值,因为需要在本文后面的分配步骤中使用此值。在此示例中,
id值为/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-gremlin/gremlinRoleDefinitions/00000000-0000-0000-0000-000000000004。 此示例使用虚构数据,标识符与此示例不同。创建名为
role-definition.json的新 JSON 文件。 在此文件中,创建一个资源定义,用于指定要允许的数据操作。用于
az cosmosdb gremlin role definition create创建角色定义。 将role-definition.json用作--body参数的输入。az cosmosdb gremlin role definition create \ --account-name <account-name> \ --resource-group <resource-group> \ --body @role-definition.json再次列出所有角色定义,并记录
id新自定义角色的属性。使用
az cosmosdb gremlin role assignment create分配新角色。 使用先前记录的角色定义标识符、你的身份的唯一标识符以及范围(账户、数据库或图)。az cosmosdb gremlin role assignment create \ --account-name <account-name> \ --resource-group <resource-group> \ --role-definition-id <role-definition-id> \ --principal-id <principal-id> \ --scope /使用
az cosmosdb gremlin role assignment list列出你的账户的所有角色分配,并验证你的角色分配。az cosmosdb gremlin role assignment list \ --account-name <account-name> \ --resource-group <resource-group>
首先,使用
az cosmsodb show获取 Gremlin 帐户的现有Azure Cosmos DB的资源标识符,并将其存储在变量中。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/gremlinRoleDefinitions?api-version=2023-04-15然后,使用
az rest列出与 Gremlin 帐户Azure Cosmos DB关联的所有角色定义。 最后,查看输出并找到名为Cosmos DB Built-in Data Contributor的角色定义。 输出包含属性中id角色定义的唯一标识符。 记录此值,因为需要在本文后面的分配步骤中使用此值。[ ..., { "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-gremlin/gremlinRoleDefinitions/00000000-0000-0000-0000-000000000004", "name": "00000000-0000-0000-0000-000000000004", "properties": { "assignableScopes": [ "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-gremlin" ], "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/gremlinRoleDefinitions" } ... ]在此示例中,
id值为/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-gremlin/gremlinRoleDefinitions/00000000-0000-0000-0000-000000000004。 此示例使用虚构数据,标识符与此示例不同。 此示例输出被截断。创建新的 Bicep 文件以定义角色定义。 将文件命名为
data-plane-role-definition.bicep。 将以下数据操作添加到定义:数据操作 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 Gremlin.' @description('Name of the Azure Cosmos DB for Gremlin account.') param accountName string @description('Name of the role definition.') param roleDefinitionName string = 'API for Gremlin Data Plane Owner' resource account 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' existing = { name: accountName } resource definition 'Microsoft.DocumentDB/databaseAccounts/gremlinRoleDefinitions@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 基于角色的访问控制原生实现中,scope 是指帐户内要应用权限的资源范围粒度。 在最高级别,可以使用最大的作用域将数据平面基于角色的访问控制分配限定到整个帐户。 此范围包括帐户中的所有数据库和容器:
/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 参数文件。 在此参数文件中,将 Gremlin 帐户现有Azure Cosmos DB的名称分配给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/gremlinRoleDefinitions/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/gremlinRoleDefinitions/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 Gremlin.' @description('Name of the Azure Cosmos DB for Gremlin 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 参数文件。 在此参数文件中,将 Gremlin 帐户现有Azure Cosmos DB的名称分配给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-AzCosmosDBGremlinRoleDefinition列出与 Gremlin 帐户Azure Cosmos DB关联的所有角色定义。Get-AzCosmosDBGremlinRoleDefinition \ -AccountName <account-name> \ -ResourceGroupName <resource-group>查看输出并找到名为
Cosmos DB Built-in Data Contributor的角色定义。 输出包含属性中Id角色定义的唯一标识符。 记录此值,因为需要在本文后面的分配步骤中使用此值。使用
New-AzCosmosDBGremlinRoleDefinition和描述要允许的权限的 JSON 文件创建新的角色定义。New-AzCosmosDBGremlinRoleDefinition \ -AccountName <account-name> \ -ResourceGroupName <resource-group> \ -InputObject (Get-Content -Raw -Path ./role-definition.json | ConvertFrom-Json)再次列出所有角色定义,并记录
Id新自定义角色的值。使用
New-AzCosmosDBGremlinRoleAssignment分配新角色。 使用先前记录的角色定义标识符、你的身份的唯一标识符以及范围(账户、数据库或图)。New-AzCosmosDBGremlinRoleAssignment \ -AccountName <account-name> \ -ResourceGroupName <resource-group> \ -RoleDefinitionId <role-definition-id> \ -PrincipalId <principal-id> \ -Scope /查看你的账户的所有角色分配,并验证你的角色分配。
Get-AzCosmosDBGremlinRoleAssignment \ -AccountName <account-name> \ -ResourceGroupName <resource-group>
Warning
Azure 门户中不支持管理数据平面的基于角色的访问控制。
在代码中验证数据平面基于角色的访问
使用应用程序代码和Azure SDK验证是否已正确授予访问权限。
using Azure.Identity;
using Azure.Core;
using Azure.Identity;
using Microsoft.Azure.Cosmos.Gremlin;
ManagedIdentityCredential defaultCredential = new ManagedIdentityCredential();
var scopes = new string[] { $"https://cosmos.azure.cn/.default" };
CancellationTokenSource cts = new CancellationTokenSource();
var accessToken = await defaultCredential.GetTokenAsync(new TokenRequestContext(scopes), cts.Token);
var credentialString = accessToken.Token;
var server = new GremlinServer(
hostname: "<account-name>.gremlin.cosmos.azure.cn",
port: 443,
username: "/dbs/<database-name>/colls/<graph-name>",
password: credentialString,
enableSsl: true
);
var client = new GremlinClient(
gremlinServer: server,
graphSONReader: new GraphSON3Reader(),
graphSONWriter: new GraphSON2Writer(),
GremlinClient.GraphSON2MimeType
);
const { DefaultAzureCredential } = require('@azure/identity');
const gremlin = require('gremlin');
const credential = new DefaultAzureCredential();
const tokenResponse = await credential.getToken('https://cosmos.azure.cn/.default');
const accessToken = tokenResponse.token;
const credentials = new gremlin.driver.auth.PlainTextSaslAuthenticator(
`/dbs/<database-name>/colls/<graph-name>`,
accessToken
);
const client = new gremlin.driver.Client(
`https://<account-name>.gremlin.cosmos.azure.cn:443/`,
{
authenticator: credentials,
traversalSource: 'g',
mimeType: 'application/vnd.gremlin-v2.0+json',
}
);
from azure.identity import ManagedIdentityCredential
from gremlin_python.driver import client, serializer
credential = ManagedIdentityCredential()
access_token = credential.get_token(SCOPE)
credential_string = access_token.token
gremlin_client = client.Client(
url="wss://<account-name>.gremlin.cosmos.azure.cn",
traversal_source="g",
username="/dbs/<database-name>/colls/<graph-name>}",
password=f"{credential_string}",
message_serializer=serializer.GraphSONSerializersV2d0(),
)
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.core.credential.TokenRequestContext;
import com.azure.core.credential.AccessToken;
import org.apache.tinkerpop.gremlin.driver.Cluster;
import org.apache.tinkerpop.gremlin.driver.Client;
import org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV2d0;
TokenCredential credential = new DefaultAzureCredentialBuilder().build();
TokenRequestContext requestContext = new TokenRequestContext().addScopes(scope);
AccessToken accessToken = credential.getToken(requestContext).block();
String credentialString = accessToken.getToken();
String resourcePath = "/dbs/" + "<database-name>" + "/colls/" + "<graph-name>";
Cluster cluster = Cluster.build()
.addContactPoint("<account-endpoint>")
.port(443)
.credentials(resourcePath, credentialString)
.enableSsl(true)
.maxWaitForConnection(100000)
.serializer(new GraphSONMessageSerializerV2d0())
.create();
Client client = cluster.connect();
相关内容
- 保护你的 Azure Cosmos DB for Apache Gremlin 帐户
- 适用于 Apache Gremlin 控制平面角色的 Azure Cosmos DB
- 适用于 Apache Gremlin 控制平面权限的 Azure Cosmos DB
- 适用于 Apache Gremlin 数据平面角色的 Azure Cosmos DB
- 适用于 Apache Gremlin 数据平面权限的 Azure Cosmos DB