排查 Azure RBAC 的问题

本文介绍与 Azure 基于角色的访问控制 (Azure RBAC) 相关的问题的一些常见解决方案。

限制

症状 -无法创建更多角色分配

尝试分配角色时,收到以下错误消息:

No more role assignments can be created (code: RoleAssignmentLimitExceeded)

原因

Azure 支持每个订阅最多具有 4,000 个角色分配。 此限制包括订阅、资源组和资源范围内的角色分配,但不包括管理组范围内的角色分配。

注意

对于 Azure 中国世纪互联等专用云,每个订阅的限制为 2000 个角色分配。

解决方案

尝试减少订阅中的角色分配数。 可通过以下方式减少角色分配数:

  • 将用户添加到组,并改为向组分配角色。
  • 结合使用多个内置角色和一个自定义角色。
  • 在较高的范围(例如订阅或管理组)进行常见的角色分配。
  • 如果你有 Azure AD Premium P2,请在 Azure AD Privileged Identity Management 中创建符合条件的角色分配,而不要永久分配角色。
  • 添加额外的订阅。

若要获取角色分配数,可以查看 Azure 门户中“访问控制(IAM)”页上的图表。 还可以使用以下 Azure PowerShell 命令:

$scope = "/subscriptions/<subscriptionId>"
$ras = Get-AzRoleAssignment -Scope $scope | Where-Object {$_.scope.StartsWith($scope)}
$ras.Count

症状 - 无法在管理组范围内创建更多角色分配

无法在管理组范围内分配角色。

原因

Azure 对于每个管理组最多支持 500 个角色分配。 此限制不同于每个订阅的角色分配限制。

注意

每个管理组的角色分配数限制 500 是固定的,无法提高。

解决方案

尝试减少管理组中的角色分配数。

Azure 角色分配

症状 - 无法分配角色

无法在 Azure 门户的“访问控制(IAM)”中分配角色,因为“添加”>“添加角色分配”选项被禁用,或者因为出现以下权限错误:

The client with object id does not have authorization to perform action

原因

当前登录时使用的用户无权在所选范围内分配角色。

解决方案

确保你当前登录时使用的用户分配有一个角色,该角色在你要尝试分配角色的范围内拥有 Microsoft.Authorization/roleAssignments/write 权限,例如所有者用户访问管理员

症状 - 无法使用服务主体通过 Azure CLI 分配角色

你正在使用服务主体通过 Azure CLI 分配角色,并出现以下错误:

Insufficient privileges to complete the operation

例如,假设你有一个服务主体,并对其分配了“所有者”角色,并且你尝试使用 Azure CLI 创建以下角色分配作为服务主体:

az login --service-principal --username "SPNid" --password "password" --tenant "tenantid"
az role assignment create --assignee "userupn" --role "Contributor"  --scope "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}"

原因

Azure CLI 可能正尝试在 Azure AD 中查找被分派人标识,但服务主体在默认情况下无法读取 Azure AD。

解决方案

可通过两种方式解决此错误。 第一种方法是将目录读取器角色分配给服务主体,以便它能够读取目录中的数据。

第二种方法是使用 --assignee-object-id 参数而不是 --assignee 来创建角色分配。 通过使用 --assignee-object-id,Azure CLI 将跳过 Azure AD 查找。 你需要获取要为其分配角色的用户、组或应用程序的对象 ID。 有关详细信息,请参阅使用 Azure CLI 分配 Azure 角色

az role assignment create --assignee-object-id 11111111-1111-1111-1111-111111111111  --role "Contributor" --scope "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}"

症状 - 使用 REST API 或 ARM 模板分配角色有时会失败

创建新的服务主体并立即尝试向该服务主体分配角色,但角色分配有时会失败。

原因

原因可能是有复制延迟。 服务主体是在一个区域中创建的;但是,角色分配可能发生在尚未复制服务主体的另一个区域中。

解决方案

请在创建角色分配时将 principalType 属性设置为 ServicePrincipal。 还必须将角色分配的 apiVersion 设置为 2018-09-01-preview 或更高版本。 有关详细信息,请参阅使用 REST API 向新服务主体分配 Azure 角色使用 Azure 资源管理器模板向新服务主体分配 Azure 角色

症状 - ARM 模板角色分配返回 BadRequest 状态

尝试部署向服务主体分配角色的 Bicep 文件或 ARM 模板时,会收到错误:

Tenant ID, application ID, principal ID, and scope are not allowed to be updated. (code: RoleAssignmentUpdateNotPermitted)

例如,如果你为托管标识创建角色分配,然后删除托管标识并重新创建它,则新托管标识具有不同的主体 ID。 如果尝试再次部署角色分配并使用相同的角色分配名称,部署将失败。

原因

角色分配 name 不是唯一的,它被视为更新。

角色分配由其名称唯一标识,这是一个全局唯一标识符 (GUID)。 即使在不同的 Azure 订阅中,也不能创建具有相同名称的两个角色分配。 也不能更改现有角色分配的属性。

解决方案

为角色分配 name 提供一个幂等唯一值。 创建一个使用相同作用域、主体 ID 和角色 ID 的 GUID 是一种很好的做法。 可以使用 guid() 函数来帮助你为角色分配名称创建确定性的 GUID,如以下示例所示:

resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
  name: guid(resourceGroup().id, principalId, roleDefinitionId)
  properties: {
    roleDefinitionId: roleDefinitionId
    principalId: principalId
    principalType: principalType
  }
}

有关详细信息,请参阅使用 Bicep 创建 Azure RBAC 资源

症状 - 未找到标识的角色分配

在 Azure 门户的角色分配列表中,你会注意到安全主体(用户、组、服务主体或托管标识)列为“未找到标识”,类型为“未知”。

Azure 角色分配中列出“未找到标识”

如果使用 Azure PowerShell 列出此角色分配,则可能看到空的 DisplayNameSignInName,或者 UnknownObjectType 值。 例如,Get-AzRoleAssignment 返回类似于以下输出的角色分配:

RoleAssignmentId   : /subscriptions/11111111-1111-1111-1111-111111111111/providers/Microsoft.Authorization/roleAssignments/22222222-2222-2222-2222-222222222222
Scope              : /subscriptions/11111111-1111-1111-1111-111111111111
DisplayName        :
SignInName         :
RoleDefinitionName : Storage Blob Data Contributor
RoleDefinitionId   : ba92f5b4-2d11-453d-a403-e96b0029c9fe
ObjectId           : 33333333-3333-3333-3333-333333333333
ObjectType         : User
CanDelegate        : False

同样,如果使用 Azure CLI 列出此角色分配,则可能看到空的 principalName。 例如,az role assignment list 返回类似于以下输出的角色分配:

{
    "canDelegate": null,
    "id": "/subscriptions/11111111-1111-1111-1111-111111111111/providers/Microsoft.Authorization/roleAssignments/22222222-2222-2222-2222-222222222222",
    "name": "22222222-2222-2222-2222-222222222222",
    "principalId": "33333333-3333-3333-3333-333333333333",
    "principalName": "",
    "roleDefinitionId": "/subscriptions/11111111-1111-1111-1111-111111111111/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe",
    "roleDefinitionName": "Storage Blob Data Contributor",
    "scope": "/subscriptions/11111111-1111-1111-1111-111111111111",
    "type": "Microsoft.Authorization/roleAssignments"
}

原因 1

你最近在创建角色分配时邀请了用户,但此安全主体可能仍处于跨区域的复制过程中。

解决方案 1

稍等片刻并刷新角色分配列表。

原因 2

你删除了具有角色分配的安全主体。 如果将角色分配给安全主体,然后在不先删除角色分配的情况下删除该安全主体,则该安全主体类型将列为“未找到标识”,类型为“未知” 。

解决方案 2

在删除安全主体的情况下,保留这些角色分配没有问题。 如果需要,可以使用与其他角色分配相似的步骤删除这些角色分配。 有关如何删除角色分配的信息,请参阅删除 Azure 角色分配

在 PowerShell 中,如果尝试通过对象 ID 和角色定义名称来删除角色分配,而多个角色分配与参数相匹配,则会出现错误消息:The provided information does not map to a role assignment。 以下输出显示了错误消息示例:

PS C:\> Remove-AzRoleAssignment -ObjectId 33333333-3333-3333-3333-333333333333 -RoleDefinitionName "Storage Blob Data Contributor"

Remove-AzRoleAssignment : The provided information does not map to a role assignment.
At line:1 char:1
+ Remove-AzRoleAssignment -ObjectId 33333333-3333-3333-3333-333333333333 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : CloseError: (:) [Remove-AzRoleAssignment], KeyNotFoundException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Resources.RemoveAzureRoleAssignmentCommand

如果出现此错误消息,请确保还指定了 -Scope-ResourceGroupName 参数。

PS C:\> Remove-AzRoleAssignment -ObjectId 33333333-3333-3333-3333-333333333333 -RoleDefinitionName "Storage Blob Data Contributor" - Scope /subscriptions/11111111-1111-1111-1111-111111111111

症状 - 无法删除最后一个所有者角色分配

你尝试删除订阅的最后一个所有者角色分配,并看到以下错误:

Cannot delete the last RBAC admin assignment

原因

不支持删除订阅的上一个“所有者”角色分配,这样是为了避免孤立订阅。

解决方案

如果你是租户的全局管理员或订阅的经典管理员(服务管理员或共同管理员),则可以删除订阅范围内的最后一个所有者(或用户访问管理员)角色分配。 在这种情况下,不会删除任何约束。 但是,如果调用来自其他某个主体,则你将无法删除订阅范围内的上一个所有者角色分配。

症状 - 移动资源后角色分配未移动

原因

如果移动的资源具有直接分配给该资源(或子资源)的 Azure 角色,则该角色分配不会移动,将会变成孤立状态。

解决方案

移动资源后,必须重新创建角色分配。 最终会自动删除孤立的角色分配,但最好是在移动资源之前删除角色分配。 若要了解如何移动资源,请参阅将资源移到新资源组或订阅

症状 - 未检测到角色分配更改

你最近添加或更新了角色分配,但未检测到更改。 你可能会看到以下消息:Status: 401 (Unauthorized)

原因 1

Azure 资源管理器有时会缓存配置和数据以提高性能。 分配角色或删除角色分配时,更改最多可能需要 30 分钟才能生效。

解决方案 1

如果使用的是 Azure 门户、Azure PowerShell 或 Azure CLI,则可以通过注销和登录来强制刷新角色分配更改。 如果使用 REST API 调用进行角色分配更改,则可以通过刷新访问令牌来强制刷新。

如果在管理组范围添加或删除某个角色分配,并且该角色具有 DataActions,对数据平面的访问权限在几个小时内可能不会更新。 这仅适用于管理组范围和数据平面。

原因 2

你将托管标识添加到组并为该组分配了角色。 用于托管标识的后端服务将为每个资源 URI 维护缓存约 24 小时。

解决方案 2

对托管标识的组或角色成员身份的更改可能需要几个小时才能生效。 有关详细信息,请参阅使用托管标识进行授权的限制

症状 - 使用 PowerShell 删除角色分配需要几分钟时间

使用 Remove-AzRoleAssignment 命令删除角色分配。 然后使用 Get-AzRoleAssignment 命令确认已为安全主体删除角色分配。 例如:

Get-AzRoleAssignment -ObjectId $securityPrincipalObject.Id

Get-AzRoleAssignment 命令指示未删除角色分配。 但是,如果你等待 5-10 分钟并再次运行 Get-AzRoleAssignment,则输出指示已删除角色分配。

原因

角色分配已被删除。 但是,为了提高性能,PowerShell 在列出角色分配时使用缓存。 刷新缓存可能会有大约 10 分钟的延迟。

解决方案

不要列出安全主体的角色分配,而是列出订阅范围内的所有角色分配并过滤输出。 例如,以下命令:

$validateRemovedRoles = Get-AzRoleAssignment -ObjectId $securityPrincipalObject.Id 

可以用以下命令代替:

$validateRemovedRoles = Get-AzRoleAssignment -Scope /subscriptions/$subId | Where-Object -Property ObjectId -EQ $securityPrincipalObject.Id

自定义角色

症状 - 无法更新自定义角色

无法更新现有的自定义角色。

原因

当前登录时使用的用户无权更新自定义角色。

解决方案

检查当前登录时使用的用户是否分配有具有 Microsoft.Authorization/roleDefinition/write 权限的角色,例如所有者用户访问管理员

症状 - 无法创建或更新自定义角色

尝试创建或更新自定义角色时,出现类似于以下内容的错误:

The client '<clientName>' with object id '<objectId>' has permission to perform action 'Microsoft.Authorization/roleDefinitions/write' on scope '/subscriptions/<subscriptionId>'; however, it does not have permission to perform action 'Microsoft.Authorization/roleDefinitions/write' on the linked scope(s)'/subscriptions/<subscriptionId1>,/subscriptions/<subscriptionId2>,/subscriptions/<subscriptionId3>' or the linked scope(s)are invalid

原因

此错误通常表示你无权访问自定义角色中的一个或多个可分配范围

解决方案

请尝试以下做法:

  • 查看谁可以创建、删除、更新或查看自定义角色,检查你是否有权为所有可分配范围创建或更新自定义角色。
  • 如果没有权限,请要求管理员在可分配范围内为你分配具有 Microsoft.Authorization/roleDefinitions/write 操作的角色,例如所有者用户访问管理员
  • 检查自定义角色中的所有可分配范围是否有效。 如果无效,请删除任何无效的可分配范围。

有关详细信息,请参阅使用 Azure 门户的自定义角色教程。

症状 - 无法删除自定义角色

无法删除自定义角色并收到以下错误消息:

There are existing role assignments referencing role (code: RoleDefinitionHasAssignments)

原因

仍有角色分配在使用自定义角色。

解决方案

删除使用自定义角色的角色分配,然后再次尝试删除自定义角色。 有关详细信息,请参阅查找角色分配以删除自定义角色

症状 - 无法将多个管理组添加为可分配范围

尝试创建或更新自定义角色时,无法将多个管理组添加为可分配范围。

原因

只能在自定义角色的 AssignableScopes 中定义一个管理组。 将管理组添加到 AssignableScopes 的功能目前为预览版。

解决方案

在自定义角色的 AssignableScopes 中定义一个管理组。 若要详细了解自定义角色和管理组,请参阅使用 Azure 管理组来组织资源

症状 - 无法将数据操作添加到自定义角色

尝试创建或更新自定义角色时,无法添加数据操作或出现以下消息:

You cannot add data action permissions when you have a management group as an assignable scope

原因

你正在尝试创建一个自定义角色,该角色具有数据操作并将管理组作为可分配范围。 无法在管理组范围内分配具有 DataActions 的自定义角色。

解决方案

创建将一个或多个订阅作为可分配范围的自定义角色。 若要详细了解自定义角色和管理组,请参阅使用 Azure 管理组来组织资源

症状 - 无法创建更多角色定义

尝试创建新的自定义角色时,收到以下消息:

Role definition limit exceeded. No more role definitions can be created (code: RoleDefinitionLimitExceeded)

原因

Azure 在一个目录中最多支持 5000 个自定义角色。 (Azure 中国世纪互联的限制为 2,000 个自定义角色。)

解决方案

尝试减少自定义角色的数量。

访问被拒绝或权限错误

症状 - 授权失败

尝试创建资源时,收到以下错误消息:

The client with object id does not have authorization to perform action over scope (code: AuthorizationFailed)

原因

当前登录时使用的用户对所选范围内的资源没有写入权限。

解决方案

检查当前登录时使用的用户所分配的角色是否对所选范围内的资源具有写入权限。 例如,若要管理某个资源组中的虚拟机,则你应当在该资源组(或父作用域)中具有虚拟机参与者角色。 有关每个内置角色的权限列表,请参阅 Azure 内置角色

Azure 功能被禁用

症状 - 某些 Web 应用功能被禁用

用户对 Web 应用具有读取访问权限,某些功能被禁用。

原因

如果向用户授予对 Web 应用的读取访问权限,某些功能会被禁用,这可能不是你所期望的。 以下管理功能需要对 Web 应用具有写入访问权限,并且在任何只读方案中均不可用。

  • 命令(例如启动、停止等。)
  • 更改设置(如常规配置、缩放设置、备份设置和监视设置)
  • 访问发布凭据和其他机密(如应用设置和连接字符串)
  • 流式处理日志
  • 资源日志配置
  • 控制台(命令提示符)
  • 活动和最新部署(适用于本地 Git 持续部署)
  • 估计费用
  • Web 测试
  • 虚拟网络(只在虚拟网络是由具有写入权限的用户在以前配置时,才对读者可见)。

解决方案

分配对 Web 应用具有写入权限的参与者或其他 Azure 内置角色

症状 - 某些 Web 应用资源被禁用

用户对 Web 应用具有写入访问权限,某些功能被禁用。

原因

由于存在几个相互作用的不同资源,Web 应用程序是复杂的。 下面是包含几个网站的典型资源组:

Web 应用程序资源组

因此,如果只授予某人对 Web 应用的访问权限,则 Azure 门户中的网站边栏选项卡上的很多功能将被禁用。

这些项需要对与网站对应的应用服务计划具有写入访问权限:

  • 查看 Web 应用的定价层(“免费”或“标准”)
  • 规模配置(实例数、虚拟机大小、自动缩放设置)
  • 配额(存储空间、带宽、CPU)

这些项需要对包含网站的整个资源组具有写入权限:

  • TLS/SSL 证书和绑定(TLS/SSL 证书可以在同一资源组和地理位置中的站点之间共享)
  • 警报规则
  • 自动缩放设置
  • Application Insights 组件
  • Web 测试

解决方案

分配一个对应用服务计划或资源组具有写入权限的 Azure 内置角色

症状 - 某些虚拟机功能被禁用

用户可以访问虚拟机,但某些功能被禁用。

原因

与 Web 应用类似,虚拟机边栏选项卡上的某些功能需要对虚拟机或资源组中的其他资源具有写访问权限。

虚拟机与域名、虚拟网络、存储帐户和警报规则相关。

这些项需要对虚拟机具有写访问权限:

  • 终结点
  • IP 地址
  • 磁盘
  • 扩展

这些项需要对虚拟机和其所在的资源组(以及域名)具有写入访问权限:

  • 可用性集
  • 负载均衡集
  • 警报规则

如果无法访问以上任何磁贴,则需要让管理员提供对资源组的“参与者”访问权限。

解决方案

分配一个对虚拟机或资源组具有写入权限的 Azure 内置角色

症状 - 某些函数应用功能被禁用

用户可以访问函数应用,但某些功能被禁用。 例如,他们可以单击“平台功能”选项卡,然后单击“所有设置”查看与函数应用(类似于 Web 应用)相关的一些设置,但无法修改任何这些设置。

原因

Azure Functions 的某些功能需要写入权限。 例如,如果给用户分配读者角色,他们将无法查看函数应用中的函数。 门户将显示 (无访问权限)。

函数应用无访问权限

解决方案

分配一个对函数应用或资源组具有写入权限的 Azure 内置角色

将订阅转移到另一目录

症状 - 转移订阅后,所有角色分配都被删除

原因

将 Azure 订阅转移到其他 Azure AD 目录时,所有角色分配都从源 Azure AD 目录中永久删除,而不会迁移到目标 Azure AD 目录。

解决方案

必须在目标目录中重新创建角色分配。 此外,还需手动重新创建 Azure 资源的托管标识。 有关详细信息,请参阅将 Azure 订阅转移到其他 Azure AD 目录托管标识的常见问题解答和已知问题

症状 - 转移订阅后无法访问订阅

解决方案

如果你是 Azure AD 全局管理员并且在目录之间转移某个订阅后对其没有访问权限,请使用“Azure 资源的访问权限管理”开关暂时提升你的访问权限来获取对订阅的访问权限。

经典订阅管理员

如果遇到服务管理员或共同管理员方面的问题,请参阅经典订阅管理员角色、Azure 角色和 Azure AD 角色

后续步骤