将基于角色的控制平面访问控制与 Azure Cosmos DB for NoSQL 配合使用

适用范围: NoSQL

此图显示部署指南序列中的当前位置(“基于角色的访问控制”)。

部署指南序列图,包括以下位置,顺序为:概述、概念、准备、基于角色的访问控制、网络和参考。 当前突出显示了“基于角色的访问控制”位置。

本文逐步介绍了授予标识访问权限以管理 Azure Cosmos DB for NoSQL 帐户及其资源的步骤。

重要

本文中的步骤仅涵盖控制平面访问,以对帐户层次结构中任何资源的帐户本身执行操作。 要了解如何管理项和执行数据平面的查询,请参阅授予数据平面基于角色的访问权限

先决条件

  • 具有活动订阅的 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

准备角色定义

首先,必须准备包含 actions 列表的角色定义,以授予在 Azure Cosmos DB 中管理帐户资源的权限。

使用 az role definition list 列出与 Azure Cosmos DB 帐户关联的所有角色定义。 查看输出并找到名为 Cosmos DB 内置数据参与者的角色定义。 输出包含属性中 id 角色定义的唯一标识符。 记下此值,因为本指南后面的工作分配步骤需要使用此值。

az role definition list \
    --name "Cosmos DB Operator"
[
  {
    "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 中的所有角色定义中都是全局唯一的。

  1. 登录到 Azure 门户 (https://portal.azure.cn)。

  2. 在全局搜索栏中输入资源组

    Azure 门户中的全局搜索栏的屏幕截图。

  3. 在“服务”中,选择“资源组”

    搜索菜单中选择的“资源组”选项的屏幕截图。

  4. 在“资源组”窗格,请选择现有资源组。

    订阅资源组列表中的现有资源组的屏幕截图。

    注意

    此示例屏幕截图包括 msdocs-identity-example 资源组。 实际的资源组名称可能有所不同。

  5. 在资源组的窗格中,在服务菜单中选择“访问控制 (IAM)”

    资源组的服务菜单中的“访问控制 (IAM)”选项的屏幕截图。

  6. 在“访问控制 (IAM)”窗格中,选择“角色”

    “访问控制 (IAM)”窗格中“角色”选项的屏幕截图。

  7. 在“角色”部分中,使用 Cosmos DB 搜索短语,找到 Cosmos DB 操作员角色定义。 然后,选择与该定义关联的“视图”选项。

    当前可分配范围中角色定义列表的屏幕截图,其中筛选为仅包含标题中包含“Cosmos DB”的定义。

  8. 在 Cosmos DB 操作员角色定义对话框中,观察分配为此角色定义的一部分的操作。

    “Cosmos DB 操作员”对话框的屏幕截图,其中包含有关内置角色定义的详细信息。

  9. 关闭 Cosmos DB 操作员角色定义对话框。

使用 Get-AzRoleDefinition 列出与 Azure Cosmos DB 帐户关联的所有角色定义。 查看输出并找到名为 Cosmos DB 内置数据参与者的角色定义。 输出包含属性中 Id 角色定义的唯一标识符。 记下此值,因为本指南后面的工作分配步骤需要使用此值。

$parameters = @{
    Name = "Cosmos DB Operator"
}
Get-AzRoleDefinition @parameters
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 中的所有角色定义中都是全局唯一的。

将角色分配给标识

现在,将新定义的角色分配给标识,以便应用程序可以访问 Azure Cosmos DB 中的资源。

重要

此分配任务要求你已拥有要授予基于角色的访问控制权限的任何标识的唯一标识符。

  1. 使用 az group show 获取当前资源组的元数据。

    az group show \
        --name "<name-of-existing-resource-group>"
    
  2. 观察上一命令的输出。 记录此资源组的 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。 此示例使用虚构数据,而你的标识符与此示例不同。 这是截断的输出示例。

  3. 使用 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/ffffffff-eeee-dddd-cccc-bbbbbbbbbbb0" \
        --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/ffffffff-eeee-dddd-cccc-bbbbbbbbbbb0。 同样,角色标识符将不同。

  4. 观察 命令的输出。 输出包含属性中 id 分配的唯一标识符。

    {
      "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleAssignments/ffffffff-eeee-dddd-cccc-bbbbbbbbbbb0",
      "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/ffffffff-eeee-dddd-cccc-bbbbbbbbbbb0",
      "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/ffffffff-eeee-dddd-cccc-bbbbbbbbbbb0,这是另一个虚构的示例。

  5. 重复这些步骤,从要使用的任何其他标识授予对帐户的访问权限。

    提示

    可以根据需要为任意数量的标识重复这些步骤。 通常,这些步骤至少重复一次,以允许开发人员使用人工标识访问帐户,并允许应用程序使用托管标识进行访问。

  1. 创建新的 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
      }
    }
    
  2. 创建名为 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>'
    
  3. 使用 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
    
  4. 重复这些步骤,从要使用的任何其他标识授予对帐户的访问权限。

    提示

    可以根据需要为任意数量的标识重复这些步骤。 通常,这些步骤至少重复一次,以允许开发人员使用人工标识访问帐户,并允许应用程序使用托管标识进行访问。

  1. 在“访问控制 (IAM)”窗格中,选择“添加”,然后“添加角色分配”

    “添加”选项的“访问控制 (IAM)”菜单中“添加角色分配”选项的屏幕截图。

  2. 在“角色”窗格中,搜索 Azure Cosmos DB,然后选择本指南前面创建的 Azure Cosmos DB 控制平面所有者角色。 然后选择下一步

    用于添加角色分配的“角色”窗格的屏幕截图。

    提示

    可以选择筛选角色列表,以仅包含自定义角色。

  3. 在“成员”窗格中,选择“选择成员”选项。 在成员对话框中,选择要为 Azure Cosmos DB 帐户授予此级别访问权限的标识,然后使用“选择”选项来确认选择。

    用于添加角色分配的“成员”窗格的屏幕截图。

    用于添加角色分配的标识选择对话框的屏幕截图。

    注意

    此屏幕截图演示了一个名为“Kai Carter”和主体为 kai@adventure-works.com 的示例用户。

  4. 返回“成员”窗格中,查看所选成员,然后选择“审阅 + 分配”

    “成员”窗格的屏幕截图,其中选择了角色分配的标识。

  5. 在“审阅 + 分配”窗格中,查看新角色分配的指定选项。 最后,选择“查看 + 分配”。

    角色分配的“审阅 + 创建”窗格的屏幕截图。

  6. 等待门户完成角色分配的创建。

  1. 使用 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
    
  2. 观察 命令的输出。 输出包含属性中 RoleAssignmentId 分配的唯一标识符。

    RoleAssignmentName : ffffffff-5555-6666-7777-aaaaaaaaaaaa
    RoleAssignmentId   : /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleAssignments/ffffffff-eeee-dddd-cccc-bbbbbbbbbbb0
    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/ffffffff-eeee-dddd-cccc-bbbbbbbbbbb0,这是另一个虚构的示例。 为清楚起见,这是部署的典型输出的子集。

  3. 重复这些步骤,从要使用的任何其他标识授予对帐户的访问权限。

    提示

    可以根据需要为任意数量的标识重复这些步骤。 通常,这些步骤至少重复一次,以允许开发人员使用人工标识访问帐户,并允许应用程序使用托管标识进行访问。

在代码中验证控制平面访问

最后,使用首选编程语言使用应用程序代码和 Azure 管理 SDK 验证是否已正确授予访问权限。

using Azure.Identity;
using Azure.ResourceManager;

DefaultAzureCredential credential = new();

ArmClient client = new(credential);

重要

此代码示例使用 NuGet 中的 Azure.ResourceManager.CosmosDBAzure.Identity 库。

下一步