使用PowerShell+Graph Rest API创建Entra ID PIM角色分配遇认证错误
问题场景
编写PowerShell代码在Azure订阅范围添加Entra ID PIM角色分配时,调用Microsoft Graph API出现以下错误:
Invoke-RestMethod: {"error":{"code":"InvalidAuthenticationToken","message":"Access token validation failure. Invalid audience.","innerError":{"date":"2023-10-30T18:29:03","request-id":"cdbbd9ac-aead-4f5f-9e55-8013d4b6a554","client-request-id":"cdbbd9ac-aead-4f5f-9e55-8013d4b6a554"}}}
原代码流程:通过服务主体连接AzAccount和MgGraph,使用(Get-AzAccessToken).Token获取令牌调用Graph API。
错误原因
Get-AzAccessToken默认获取的令牌受众是Azure Resource Manager(https://management.azure.com/),而Microsoft Graph API要求令牌受众必须是https://graph.microsoft.com/,因此令牌验证失败。
修复方案
方案1:获取针对Graph的专用令牌
修改获取令牌的代码,指定ResourceUrl为Graph的端点:
$auth_token = (Get-AzAccessToken -ResourceUrl "https://graph.microsoft.com").Token
方案2:直接使用MgGraph模块调用API(推荐)
无需手动处理令牌,利用Connect-MgGraph建立的上下文,使用Invoke-MgGraphRequest调用API,更简洁且不易出错。
完整修正代码
方式1:使用指定ResourceUrl的令牌
$subscriptionid = "subID" $tenantId = "tenantID" $clientId = "ClientID" $clientSecret = "ClientSecret" $secureClientSecret = ConvertTo-SecureString $clientSecret -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential($clientId, $secureClientSecret) Connect-AzAccount -ServicePrincipal -Credential $credential -TenantId $tenantId -Subscription $subscriptionid # 获取针对Microsoft Graph的访问令牌 $auth_token = (Get-AzAccessToken -ResourceUrl "https://graph.microsoft.com").Token $body_json = @" { "roleDefinitionId": "Azure RBAC Contributor role ID", "resourceId": "/subscriptions/My Azure Subscription ID", "subjectId": "My Entra ID group ID", "assignmentState": "Eligible", "type": "AdminAdd", "schedule": { "type": "Once", "startDateTime": "2023-11-12T23:37:43.356Z", "endDateTime": "2024-11-08T23:37:43.356Z" } } "@ $response = Invoke-RestMethod -Method POST ` -Uri "https://graph.microsoft.com/beta/privilegedAccess/azureResources/roleAssignmentRequests" ` -Body $body_json ` -Headers @{"Content-type"="application/json";"Authorization"="Bearer $auth_token"}
方式2:使用Invoke-MgGraphRequest(推荐)
$subscriptionid = "subID" $tenantId = "tenantID" $clientId = "ClientID" $clientSecret = "ClientSecret" $secureClientSecret = ConvertTo-SecureString $clientSecret -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential($clientId, $secureClientSecret) Connect-AzAccount -ServicePrincipal -Credential $credential -TenantId $tenantId -Subscription $subscriptionid # 连接MgGraph并指定所需权限 Connect-MgGraph -TenantID $tenantId -ClientSecretCredential $credential -Scopes "PrivilegedAccess.ReadWrite.AzureResources" $body = @{ roleDefinitionId = "Azure RBAC Contributor role ID" resourceId = "/subscriptions/My Azure Subscription ID" subjectId = "My Entra ID group ID" assignmentState = "Eligible" type = "AdminAdd" schedule = @{ type = "Once" startDateTime = "2023-11-12T23:37:43.356Z" endDateTime = "2024-11-08T23:37:43.356Z" } } $response = Invoke-MgGraphRequest -Method POST ` -Uri "/beta/privilegedAccess/azureResources/roleAssignmentRequests" ` -Body $body ` -ContentType "application/json"
注意事项
- 确保服务主体已被授予PrivilegedAccess.ReadWrite.AzureResources应用权限(需全局管理员同意)
- Graph API的PIM端点属于beta版本,调用时需使用
/beta路径
内容的提问来源于stack exchange,提问作者tester81

