调用graph.microsoft.com PATCH接口为Azure AD应用添加API权限报错
错误原因
核心错误是请求URI不符合Microsoft Graph API的PATCH调用规范:PATCH方法仅支持对单个具体资源实例发起修改请求,你当前使用的URI是应用集合的过滤查询端点https://graph.microsoft.com/v1.0/applications?$filter=appId eq '$appId',属于集合类端点,仅支持GET查询、POST新建操作,不支持PATCH修改,因此直接返回方法不允许的错误。
同时你的代码还存在两个潜在问题:
- 循环中每次PATCH仅提交单条权限,会直接覆盖应用已有的其他API权限,最终只会保留最后一次提交的权限
- 没有先获取目标应用的唯一对象ID,无法准确定位要修改的资源
解决方案
调整请求逻辑,先查询到目标应用的对象ID后,合并所有需要的权限,一次性对单个应用实例端点发起PATCH请求:
- 首先查询目标应用的对象ID
# 查询目标应用的对象ID(注意区分应用的appId和实例id) $targetApp = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/applications?`$filter=appId eq '$appId'" -Headers @{"Authorization" = "Bearer $AADToken"} -Method Get $targetAppObjectId = $targetApp.Value[0].id
- 构造完整权限列表后一次性提交PATCH
# 收集所有需要的权限项,不要循环提交 $resourceAccessList = @() foreach ($RoleAssignment in $RoleAssignments) { $resourceAccessList += @{ id = $RoleAssignment.Id type = "Role" } } # 对单个应用实例端点发起PATCH请求 $restSplat = @{ Method = "PATCH" Uri = "https://graph.microsoft.com/v1.0/applications/$targetAppObjectId" Headers = @{"Authorization" = "Bearer $AADToken"; "Content-Type" = "application/json"} Body = @{ requiredResourceAccess = @( @{ resourceAppId = $targetSp.appId resourceAccess = $resourceAccessList } ) } | ConvertTo-Json -Depth 4 } Invoke-RestMethod @restSplat
注意事项
- 如果需要保留应用已有的其他API权限,需要先GET获取当前
requiredResourceAccess的配置,将新权限合并到现有数组后再提交PATCH,否则会覆盖原有所有权限 - 权限配置完成后,还需要单独发起管理员同意请求,否则配置的权限不会生效
内容的提问来源于stack exchange,提问作者Nadia Hansen
相关产品推荐
相关产品推荐

