排查 Azure RBAC 的问题

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

Azure 角色分配

症状 - 禁用了“添加角色分配”选项

无法在 Azure 门户中的“访问控制(IAM)”上分配角色,因为“添加”>“添加角色分配”选项已禁用

原因

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

解决方案

请检查你当前登录时使用的用户是否分配有在你尝试分配角色的范围内具有 Microsoft.Authorization/roleAssignments/write 权限的角色,例如“基于角色的访问控制管理员”。

症状 - 未列出角色或主体

尝试在 Microsoft Azure 门户中分配角色时,不会列出某些角色或主体。 例如,在“角色”选项卡上,可以看到一组减少的角色。

受限于特定角色的角色分配屏幕截图。

或者,在“选择成员”窗格上,可以看到一组减少的主体。

受限于特定组的角色分配屏幕截图。

原因

可以添加的角色分配存在限制。 例如,你在可以分配的角色中受到约束,或者在可以向其分配角色的主体中受到约束。

解决方案

查看分配给你的角色。 检查是否存在限制可添加的角色分配的条件。

包含条件的角色分配屏幕截图。

症状 - 无法分配角色

无法分配角色,并且收到类似于以下内容的错误:

Failed to add {securityPrincipal} as {role} for {scope} : The client '{clientName}' with object id '{objectId}' does not have authorization or an ABAC condition not fulfilled to perform action 'Microsoft.Authorization/roleAssignments/write' over scope '/subscriptions/{subscriptionId}/Microsoft.Authorization/roleAssignments/{roleAssignmentId}' or the scope is invalid. If access was recently granted, please refresh your credentials.

原因 1

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

解决方案 1

请检查你当前登录时使用的用户是否分配有在你尝试分配角色的范围内具有 Microsoft.Authorization/roleAssignments/write 权限的角色,例如“基于角色的访问控制管理员”。

原因 2

可以添加的角色分配存在限制。 例如,你在可以分配的角色中受到约束,或者在可以向其分配角色的主体中受到约束。

解决方案 2

查看分配给你的角色。 检查是否存在限制可添加的角色分配的条件。

包含条件的角色分配屏幕截图。

症状 - 无法使用服务主体通过 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 可能会尝试在 Microsoft Entra ID 中查找代理人标识,并且服务主体默认无法读取 Microsoft Entra ID。

解决方案

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

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

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

症状 - 向新主体分配角色有时会失败

你在创建新的用户、组或服务主体并立即尝试将角色分配给该主体,但该角色分配有时会失败。 你收到类似于以下错误的消息:

PrincipalNotFound
Principal {principalId} does not exist in the directory {tenantId}. Check that you have the correct principal ID. If you are creating this principal and then immediately assigning a role, this error might be related to a replication delay. In this case, set the role assignment principalType property to a value, such as ServicePrincipal, User, or Group.  See https://aka.ms/docs-principaltype

原因

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

解决方案 1

如果你在使用 REST API 或 ARM 模板创建新的用户或服务主体,请在使用角色分配 - 创建 API 创建角色分配时设置 principalType 属性。

principalType apiVersion
User 2020-03-01-preview 或更高版本
ServicePrincipal 2018-09-01-preview 或更高版本

有关详细信息,请参阅使用 REST API 向新服务主体分配 Azure 角色使用 Azure 资源管理器模板向新服务主体分配 Azure 角色

解决方案 2

如果你在使用 Azure PowerShell 创建新的用户或服务主体,请在使用 New-AzRoleAssignment 创建角色分配时将 ObjectType 参数设置为 UserServicePrincipal。 解决方案 1 的那些基础 API 版本限制仍然适用。 有关详细信息,请参阅使用 Azure PowerShell 分配 Azure 角色

解决方法 3

如果你是在创建新组,请等待几分钟,然后再创建角色分配。

症状 - 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 订阅

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

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

原因

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

解决方案

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

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

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

原因 1

Azure 资源管理器有时会缓存配置和数据以提高性能。

解决方案 1

分配角色或删除角色分配时,更改最多可能需要 10 分钟才能生效。 如果使用的是 Azure 门户、Azure PowerShell 或 Azure CLI,则可以通过注销和登录来强制刷新角色分配更改。 如果使用 REST API 调用进行角色分配更改,则可以通过刷新访问令牌来强制刷新。

原因 2

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

解决方案 2

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

症状 - 未检测到管理组范围的角色分配更改

你最近在管理组范围添加或更新了角色分配,但未检测到更改。

原因

Azure 资源管理器有时会缓存配置和数据以提高性能。

解决方案

分配角色或删除角色分配时,更改最多可能需要 10 分钟才能生效。 如果在管理组范围添加或删除某个内置角色分配,并且该内置角色具有 DataActions,那么,对数据平面的访问权限在几个小时内可能不会更新。 这仅适用于管理组范围和数据平面。 无法在管理组范围内分配具有 DataActions 的自定义角色。

症状 - 未检测到针对管理组更改的角色分配

你创建了一个新的子管理组,但在父管理组上未检测到该子管理组的角色分配。

原因

Azure 资源管理器有时会缓存配置和数据以提高性能。

解决方案

子管理组的角色分配最多可能需要 10 分钟才能生效。 如果使用的是 Azure 门户、Azure PowerShell 或 Azure CLI,则可以通过注销和登录来强制刷新角色分配更改。 如果使用 REST API 调用进行角色分配更改,则可以通过刷新访问令牌来强制刷新。

症状 - 使用 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

自定义角色

故障描述 - 无法更新或删除自定义角色

你无法更新或删除现有的自定义角色。

原因 1

你当前以其身份登录的用户无权更新或删除自定义角色。

解决方案 1

请检查你当前登录时使用的用户是否分配有具有 Microsoft.Authorization/roleDefinitions/write 权限的角色,例如“用户访问管理员”。

原因 2

自定义角色包括可分配范围内的订阅,并且该订阅处于禁用状态

解决方案 2

重新激活已禁用的订阅,并根据需要更新自定义角色。 有关详细信息,请参阅重新激活已禁用的 Azure 订阅

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

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

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 中定义一个管理组。 若要详细了解自定义角色和管理组,请参阅使用 Azure 管理组来组织资源

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

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

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

原因

尝试使用数据操作以及作为可分配范围的管理组创建自定义角色。 无法在管理组范围内分配具有 DataActions 的自定义角色。

解决方案

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

访问被拒绝或权限错误

症状 - 授权失败

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

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

原因 1

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

解决方案 1

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

原因 2

当前登录的用户拥有具有以下条件的角色分配:

解决方案 2

目前,无法使用 Microsoft.Storage 数据操作和使用 GUID 比较运算符的 ABAC 条件分配角色。 下面是几个用于解决此错误的选项:

  • 如果该角色是自定义角色,请删除任何 Microsoft.Storage 数据操作
  • 修改角色分配条件,使其不使用 GUID 比较运算符

症状 - 来宾用户授权失败

当来宾用户尝试访问资源时,他们会收到类似于以下内容的错误消息:

The client '<client>' with object id '<objectId>' does not have authorization to perform action '<action>' over scope '<scope>' or the scope is invalid.

原因

来宾用户对所选范围内的资源没有权限。

解决方案

检查是否为来宾用户分配了对所选范围内的资源具有最低特权的角色。 有关详细信息,请参阅使用 Azure 门户将 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 订阅转移到其他 Microsoft Entra 目录时,将从源 Microsoft Entra 目录中永久删除所有角色分配,而不会将其迁移到目标 Microsoft Entra 目录。

解决方案

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

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

解决方案

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

经典订阅管理员

重要

经典资源和经典管理员将于 2024 年 8 月 31 日停用。 从 2024 年 3 月 26 日开始,将无法添加新的共同管理员。 此日期最近已延长。 删除不必要的共同管理员,并使用 Azure RBAC 进行精细访问控制。

有关详细信息,请参阅 Azure 经典订阅管理员

后续步骤