获取 Azure AD 主体的所有角色分配

6
我有一个Azure环境,其中包含多个订阅和资源。我的要求是,如果我传递一个用户名或SPN名称,它会给我所有Azure资源(从管理组到Azure资源),在这些资源中,该用户/ SPN拥有访问权限以及其访问权限是什么(读者/数据读取器等)的功能。
主要问题是 - 我想要PIM角色分配。有没有办法获取它?
已探索的选项:
1. https://learn.microsoft.com/en-us/rest/api/authorization/role-assignments,但这只提供每个范围的角色分配。我想要每个用户/ SPN的角色分配。 2. https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-list-portal 它不涵盖PIM分配,并且仅按订阅提供分配。 3. Azure Resource Graph Explorer - 这根本不涵盖角色分配。
除了遍历50个订阅,获取每个范围的角色分配,然后比较对象ID之外,还有更好的方法吗?

请编辑您的问题,并包括您已尝试过的内容以及遇到的问题。 - Gaurav Mantri
这就是问题所在,我找不到任何东西。RBAC API (https://learn.microsoft.com/en-us/rest/api/authorization/role-assignments) 获取每个范围的角色分配,但我想获取每个用户的角色分配。除了遍历所有订阅及其资源,再匹配用户/SPN对象ID外,我无法解决此问题。遍历如此庞大的数据,然后比较对象ID似乎也不是一个好的解决方案。因此需要查询。 - codegal
还尝试了这个 https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-list-portal 但遗憾的是它没有提供PIM分配,而且也没有PIM的GA API。 - codegal
谢谢。请编辑您的问题,并将此信息仅包含在那里。 - Gaurav Mantri
4个回答

4
@Gjoshevski分享了一个有用的命令,但您仍然需要循环遍历每个订阅以列出每个订阅上的角色分配(如果您在租户中有多个订阅)。
以下Azure CLI命令将完成此任务。
spID='<ObjectID here>' # ObjectID of an Applicatin or Service Principal
$tenantId='<TenantID here>'
az login --tenant 'Your Tenant'
$sub_ids=$(az account list --query id -o tsv)

foreach ($sub_id in $sub_ids) {
    az account set --subscription $sub_id
    "Subscription Name: $(az account show --query name)"
    az role assignment list --all --assignee $spID --include-inherited --include-groups -o table
}

请注意,上述是PowerShell语法,但使用的是Aure CLI命令。

az account list --query id 对我来说没有返回任何结果。我从未使用过JMESPath查询,但这看起来不像一个。 - undefined
同时,这并不包括问题中要求的PIM权限,只包括当前分配的权限。 - undefined
然而,它确切地返回了在订阅中资源组和资源内授予的权限。 - undefined

1

这仅适用于 azcli 所设置的订阅。有关 az cli 的正确使用方法,请参见 @rohancragg 的答案。 - Ryu S.

0
您可以使用以下 Powershell 脚本在多个订阅中获取服务主体名称的角色分配。
Connect-AzAccount
$tenantID = "yourTenantID"
$spn = "serviceprincipalname"
$user= Get-AzADUser -UserPrincipalName $spn
$subscriptions = Get-AzSubscription -TenantId $tenantID
#$subscriptions.Id
foreach ($subscription in $subscriptions) {
$set = Set-AzContext -Subscription $subscription
$set
$roleassignment= Get-AzRoleAssignment -ObjectId $user.Id
$roleassignment
}

输出:

enter image description here

参考:

安装 Azure Az PowerShell 模块 | 微软文档


感谢您的帮助。这里有两件事情:
  1. 这适用于SPN,但对于用户,它将不会给我任何PIM分配。
  2. 我希望避免重复迭代订阅的相同操作。
- codegal
2
@codegal,1.以上内容适用于用户SPN(服务主体名称)。要为SP(服务主体)执行相同操作,您可以获取azuread应用程序并匹配应用程序的服务主体的对象ID,并获取PIM。2.不幸的是,如果没有迭代,就没有直接的方法来获取此信息。 - Ansuman Bal

0
首先,为您想要查询的用户定义对象ID。连接到Graph和Azure,以便下面的所有命令都能正常工作。同时,系统上必须安装Azure CLI。
$PrincipalToQuery = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
Connect-Graph
Connect-AzAccount

然后,根据您想要查询的内容,您需要执行不同的代码。

Entra ID角色(活跃)

此命令查询用户当前活动的Entra ID角色,包括所有静态分配的角色(以及通过PIM当前启用的角色)。该命令已经考虑到通过角色可分配组获得的角色。我们添加了两个附加属性,以使输出更易理解。

$AzureRoles = Get-MgBetaRoleManagementDirectoryTransitiveRoleAssignment -All -Filter "principalId eq '$PrincipalToQuery'" -ConsistencyLevel eventual
$Output = foreach ($AzureRole in $AzureRoles) {
    $Principal = Get-MgBetaDirectoryObjectById -Ids $AzureRole.principalId
    $AzureRole | Add-Member -NotePropertyName PrincipalDisplayName -NotePropertyValue $Principal.AdditionalProperties.displayName
    $RoleDefinition = Get-MgBetaRoleManagementDirectoryRoleDefinition -UnifiedRoleDefinitionId $AzureRole.roleDefinitionId
    $AzureRole | Add-Member -NotePropertyName RoleDefinitionDisplayName -NotePropertyValue $RoleDefinition.DisplayName
    $AzureRole
}
$Output | Select-Object RoleDefinitionDisplayName,DirectoryScopeId,PrincipalDisplayName,PrincipalId,RoleDefinitionId,AppScopeId | Out-GridView

进入ID角色 - PIM(符合条件)

此命令仅返回启用PIM的进入ID角色。它不考虑通过角色可分配组传递的角色,因此我们需要手动检查主体的组,并根据此方式构建结果。根据查询的是用户还是服务主体,我们需要使用Get-MgBetaUserTransitiveMemberOfGet-MgBetaServicePrincipalTransitiveMemberOf。与上述相同,我们添加了两个额外的属性,以使输出更易理解。

$EligibleAzureRolesUnfiltered = Get-MgBetaRoleManagementDirectoryRoleEligibilityScheduleInstance -All
$PrincipalToQueryTransitiveMemberOf = Get-MgBetaUserTransitiveMemberOf -All -UserId $PrincipalToQuery
# $PrincipalToQueryTransitiveMemberOf = Get-MgBetaServicePrincipalTransitiveMemberOf -All -ServicePrincipalId $PrincipalToQuery
$EligibleAzureRoles = $EligibleAzureRolesUnfiltered | Where-Object {($_.PrincipalId -eq $PrincipalToQuery) -or ($_.PrincipalId -in $PrincipalToQueryTransitiveMemberOf.Id)}
$Output = foreach ($EligibleAzureRole in $EligibleAzureRoles) {
    $Principal = Get-MgBetaDirectoryObjectById -Ids $EligibleAzureRole.principalId
    $EligibleAzureRole | Add-Member -NotePropertyName PrincipalDisplayName -NotePropertyValue $Principal.AdditionalProperties.displayName
    $RoleDefinition = Get-MgBetaRoleManagementDirectoryRoleDefinition -UnifiedRoleDefinitionId $EligibleAzureRole.roleDefinitionId
    $EligibleAzureRole | Add-Member -NotePropertyName RoleDefinitionDisplayName -NotePropertyValue $RoleDefinition.DisplayName
    $EligibleAzureRole
}
$Output | Select-Object RoleDefinitionDisplayName,DirectoryScopeId,PrincipalDisplayName,PrincipalId,RoleDefinitionId,AppScopeId | Out-GridView

Azure资源(活动中)

此命令查询用户当前活动的Azure RBAC角色,因此包括所有静态分配的角色(以及通过PIM当前启用的角色)。该命令已经尊重通过组传递的角色(它们不必是可分配角色)。我们还包括了一个额外的查询,用于确定分配所针对的订阅,因为默认情况下,只返回订阅的ID。存在Group-Object是为了避免多次列出相同的分配(多个订阅可能从更高级别的管理组继承角色分配)。

$Subscriptions = az account list --all | ConvertFrom-Json
$Output = foreach ($Subscription in $Subscriptions) {
    # use Azure CLI because the Powershell equivalent 'Get-AzRoleAssignment -ExpandPrincipalGroups' does not expand groups for service principals
    az role assignment list --all --assignee $PrincipalToQuery --include-groups --include-inherited --subscription $Subscription.id  | ConvertFrom-Json
}
$GroupedOutput = $Output | Group-Object Id | ForEach-Object {$_.Group | Select-Object -First 1}
$GroupedOutput | ForEach-Object {
    $IsInsideSubscription = ($_.scope.split('/'))[1] -eq 'subscriptions'
    if ($IsInsideSubscription) {
        $SubscriptionId = ($_.scope.split('/'))[2]
        $SubscriptionName = (Get-AzSubscription -SubscriptionId $SubscriptionId).Name
        $_ | Add-Member -NotePropertyName subscriptionName -NotePropertyValue $SubscriptionName
    }
}
$GroupedOutput | Select-Object roleDefinitionName,scope,subscriptionName,principalName,principalId,principalType | Out-GridView

Azure资源 - PIM(符合条件)
此命令仅返回启用了PIM的Azure RBAC角色。它不考虑通过组获得的角色(它们不必是可分配的角色),因此我们需要手动检查主体的组,并根据此方式构建结果。根据查询的是用户还是服务主体,我们需要使用Get-MgBetaUserTransitiveMemberOfGet-MgBetaServicePrincipalTransitiveMemberOf。此命令返回的属性已经足够可读,因此我们可以直接输出其结果。Group-Object用于避免多次列出相同的分配(多个订阅可能从更高级别的管理组继承角色分配)。
$Subscriptions = az account list --all | ConvertFrom-Json
$PrincipalToQueryTransitiveMemberOf = Get-MgBetaUserTransitiveMemberOf -All -UserId $PrincipalToQuery
# $PrincipalToQueryTransitiveMemberOf = Get-MgBetaServicePrincipalTransitiveMemberOf -All -ServicePrincipalId $PrincipalToQuery
$Output = foreach ($Subscription in $Subscriptions) {
    $EligibleRBACRolesUnfiltered = Get-AzRoleEligibilityScheduleInstance -Scope "/subscriptions/$($Subscription.id)"
    $EligibleRBACRoles = $EligibleRBACRolesUnfiltered | Where-Object {($_.PrincipalId -eq $PrincipalToQuery) -or ($_.PrincipalId -in $PrincipalToQueryTransitiveMemberOf.Id)}
    $EligibleRBACRoles
}
$Output | Group-Object Id | ForEach-Object {$_.Group | Select-Object -First 1 RoleDefinitionDisplayName,ScopeDisplayName,PrincipalDisplayName,ScopeId,PrincipalId,RoleDefinitionId} | Out-GridView

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接