Azure 中的托管标识提供了一种安全便捷的方式来管理 Azure 资源上运行的应用程序的凭据。 本文概述了在用户分配的托管标识和系统分配的托管标识之间进行选择的最佳做法建议,可帮助你优化标识管理并减少管理开销。
与系统分配的托管标识相比,用户分配的托管标识适用的方案范围更加广泛。 有关一些场景以及用户分配或系统分配的托管标识的建议,请参阅下表。
用户分配的标识可供多个资源使用,但其生命周期与和其关联的资源的生命周期保持分离。 了解哪些资源支持托管标识。
在此生命周期,你可以分离资源创建和标识管理职责。 用户分配的标识及其角色分配可以在需要它们的资源之前进行配置。 创建资源的用户只需要访问权限即可分配用户分配的标识,无需创建新的标识或角色分配。
由于创建和删除系统分配标识的同时也会创建和删除相关资源,因此无法提前创建角色分配。 如果创建资源的用户也没有创建角色分配的权限,则此序列可能会导致基础结构部署失败。
如果你的基础结构要求多个资源需要访问相同的资源,则可以为它们分配一个用户指定的身份。 管理开销会减少,因为要管理的不同标识和角色分配更少。
若你要求每个资源都有其自己的标识或其中包含需要唯一权限集的资源,并且你希望在删除资源时也删除相应标识,则应当使用系统分配的标识。
场景 | 建议 | 注释 |
---|---|---|
使用托管标识快速创建资源(例如,临时计算) | 用户分配的标识 | 如果尝试在短时间内创建多个托管标识(例如,部署多个虚拟机,每个虚拟机都有自己的系统分配的标识)则可能会超过Microsoft Entra 对象创建速率限制,并且请求失败并出现 HTTP 429 错误。 若使用系统分配的标识快速创建或删除资源,则可能还会超出 Microsoft Entra ID 中的资源数限制。 虽然已删除的系统分配的标识不再可供任何资源访问,但它计入限制,直到 30 天后完全清除。 部署与单个用户分配标识关联的资源时,只需在 Microsoft Entra ID 中创建一个服务主体,从而避免速率限制。 使用提前创建的单个标识可降低复制延迟的风险,如果创建了多个资源,每个资源都有其自己的标识。 阅读有关 Azure 订阅服务限制的更多信息。 |
复制资源/应用程序 | 用户分配的标识 | 执行相同任务的资源(例如,重复的 Web 服务器或在应用服务和虚拟机上的应用程序中运行的相同功能)通常需要相同的权限。 通过使用相同的用户分配的标识,所需的角色分配减少,从而减少了管理开销。 资源类型可以不同。 |
合规性 | 用户分配的标识 | 如果你的组织要求所有标识创建都必须经过审批过程,则跨多个资源使用单个用户分配的标识需要比系统分配的标识更少的审批,因为系统分配的标识是在创建新资源时创建的。 |
需先进行访问,才可部署资源 | 用户分配的标识 | 有些资源可能需要在部署过程中访问特定 Azure 资源。 在这种情况下,系统分配的标识可能不会及时创建,因此应使用预先存在的用户分配标识。 |
审核日志 | 系统分配的标识 | 如果需要记录执行某项操作的特定资源(而非标识),请使用系统分配的标识。 |
权限生命周期管理 | 系统分配的标识 | 如果需要将资源的权限连同该资源一起删除,请使用系统分配的标识。 |
下方关系图将演示分别使用系统分配标识和用户分配标识来允许多个虚拟机访问两个存储帐户时出现的差异。
此图显示使用系统分配标识的四个虚拟机。 每个虚拟机获分配的角色完全相同,以使其可以访问两个存储帐户。
若将用户分配的标识与四个虚拟机关联,则只需进行 2 次角色分配,而使用系统分配标识将需进行 8 次角色分配。 如果虚拟机的标识需要更多的角色分配,则向与此标识关联的所有资源授予这些角色分配。
你还可以使用安全组来减少所需的角色分配次数。 此图显示具有系统分配的标识的四个虚拟机,这些虚拟机已添加到安全组,角色分配已添加到组(而不是系统分配的标识)。 虽然结果很类似,但此配置不提供与用户分配标识相同的资源管理器模板功能。
支持托管标识的资源可以同时使用一个系统分配标识和一个或多个用户分配标识。
此模型可让你灵活使用共享的用户分配标识,并在需要时应用精细权限。
在以下示例中,“虚拟机 3”和“虚拟机 4”可以访问存储帐户和密钥保管库,具体取决于他们在进行身份验证时使用的用户分配标识。
在以下示例中,“虚拟机 4”具有用户分配的标识,使它能够访问存储帐户和密钥保管库,具体取决于身份验证时使用哪个标识。 系统分配标识的角色分配是专门针对该虚拟机的。
查看托管身份以及自定义角色和角色分配的限制。
授予任何标识(包括托管标识)访问服务的权限时,始终授予执行所需操作所需的最低权限。 例如,如果使用托管标识从存储帐户读取数据,则无需允许该标识权限也将数据写入存储帐户。 授予额外的权限(例如,在不需要托管标识时使托管标识成为 Azure 订阅上的参与者)会增加与标识关联的安全冲击半径。 必须始终尽量减少安全冲击半径,这样在泄漏标识时可以最大限度地降低危害。
请务必注意,当为 Azure 资源(例如 Azure 逻辑应用或虚拟机)分配托管标识时,授予托管标识的所有权限现在都可供 Azure 资源使用。 这一点很重要,因为如果用户有权在此资源上安装或执行代码,则用户有权访问分配给/关联到 Azure 资源的所有标识。 托管标识的目的是向 Azure 资源上运行的代码提供对其他资源的访问权限,而无需开发人员直接处理凭据或直接将凭据放入代码中来获取该访问权限。
例如,如果向托管标识(ClientId = 1234)授予对 StorageAccount7755 的读/写访问权限,并且已分配给 LogicApp3388,则 Alice(没有对存储帐户的直接访问权限,但有权在 LogicApp3388 中执行代码 )也可以通过 执行使用托管标识的代码来读取/写入数据。
同样,如果 Alice 有权自行分配托管标识,则她可以将其分配给另一 Azure 资源,并可访问供该托管标识使用的所有权限。
一般情况下,授予用户对可以执行代码(如逻辑应用)且具有托管标识的资源的管理访问权限时,请考虑分配给用户的角色能否在资源上安装或运行代码,如果可以,则仅在用户真正需要时分配该角色。
系统分配标识会在删除资源时自动删除,而用户分配标识的生命周期独立于与之关联的任何资源。
不再需要用户分配的标识时,即使没有资源与之关联,也需要手动删除该标识。
删除系统分配或用户分配的托管标识后,相关角色分配不会自动删除。 因此,应当手动删除这些角色分配,以免超出每个订阅的角色分配数上限。
在门户中查看时,与已删除的托管标识相关联的角色分配显示为“未找到标识”。 了解详细信息。
不再与用户或服务主体关联的角色分配显示 ObjectType
值为 Unknown
。 若要删除它们,你可以通过管道将几个 Azure PowerShell 命令连接在一起,以首先获取所有角色分配,仅筛选出 ObjectType
值为 Unknown
的角色分配,然后从 Azure 中删除这些角色分配。
Get-AzRoleAssignment | Where-Object {$_.ObjectType -eq "Unknown"} | Remove-AzRoleAssignment
使用 Microsoft Entra ID 组授予对服务的访问权限是一个可简化授权过程的好方法。 思路很简单 - 向组授予权限,并将标识添加到组,以便它们继承相同的权限。 这是来自各种本地系统的成熟模式,当这些身份用于表示用户时效果良好。 在 Microsoft Entra ID 中控制授权的另一种方法是使用应用角色,通过此方法,可声明特定于应用的角色(而不是目录中作为全局概念的组)。 然后,你可以将应用角色分配给托管标识(以及用户或组)。
在这两种情况下,对于非人类标识(如 Microsoft Entra 应用程序和托管标识),目前向应用程序呈现此授权信息的确切机制并不理想。 目前使用 Microsoft Entra ID 和 Azure 基于角色的访问控制 (Azure RBAC) 的实现使用 Microsoft Entra ID 颁发的访问令牌来对每个标识进行身份验证。 如果将标识添加到组或角色中,这将在 Microsoft Entra ID 颁发的访问令牌中表示为声明。 Azure RBAC 使用这些声明来进一步评估用于允许或拒绝访问的授权规则。
鉴于标识的组和角色是访问令牌中的声明,因此任何授权更改在令牌刷新之前都不会生效。 针对人类用户,这通常不是问题,因为他们可以通过注销并再次登录(或等待令牌生存期到期,默认为 1 小时)来获取新的访问令牌。 另一方面,托管标识令牌由 Azure 的底层基础设施进行缓存,以提高性能和恢复能力:托管标识的后端服务会为每个资源 URI 维护一个缓存,有效期大约为 24 小时。 这意味着,对托管标识的组或角色成员身份所做的更改可能需要几个小时才能生效。 目前,无法强制在托管标识过期之前刷新其令牌。 如果更改某个托管标识的组或角色成员身份以添加或删除权限,则可能需要等待几个小时才能让使用该标识的 Azure 资源获得正确的访问权限。
如果这种延迟不符合你的要求,可考虑除使用令牌中的组或角色之外的其他方式。 为确保对托管标识的权限所做的更改快速生效,建议使用用户分配的托管标识对 Azure 资源进行分组,并将权限直接应用于标识,而不是在具有权限的 Microsoft Entra 组中添加或删除托管标识。 用户分配的托管标识可以像组一样使用,因为可以将它分配给一个或多个 Azure 资源来进行使用。 分配操作可以使用托管标识参与者和托管标识操作员角色进行控制。