使用Graph API与PowerShell获取合作伙伴租户域名时遇401未授权错误
问题诊断与修复方案
核心问题分析
你的脚本出现401未授权和权限不足的问题,主要源于以下几点:
- 全局登录与租户级认证的上下文冲突:开头的
Connect-*命令会建立全局认证上下文,干扰后续针对客户租户的服务主体认证。 - Graph API调用未显式传递客户租户的token:
Invoke-RestMethod默认使用全局上下文,而非你生成的客户租户专用token。 - 反钓鱼规则参数错误:策略名与规则关联的策略不匹配,且域名参数格式不符合要求。
- 权限配置或token生成逻辑存在偏差:token对应的租户ID可能不正确,或应用权限未正确授予客户租户。
分步修复
1. 清理全局认证上下文
删除脚本开头的以下命令,避免干扰租户级认证:
# 删掉这些全局登录命令 Connect-MsolService Connect-ExchangeOnline Connect-MgGraph
2. 修正Graph API的token传递
调用Graph时必须显式附加客户租户的token到请求头,确保访问的是目标租户的资源:
# 在获取域名前添加请求头配置 $headers = @{ "Authorization" = "Bearer $($graphToken.AccessToken)" } $organizationDomains = Invoke-RestMethod -Uri 'https://graph.microsoft.com/v1.0/domains?$select=id' -Method Get -Headers $headers # 提取纯域名数组,用于后续反钓鱼规则 $domainNames = $organizationDomains.value.id
3. 验证token的租户正确性
在生成token后添加验证逻辑,确保token属于当前处理的客户租户:
# 解码Graph token查看租户ID $jwtPart = $graphToken.AccessToken.Split('.')[1] $jwtPartPadded = $jwtPart.PadRight($jwtPart.Length + (4 - $jwtPart.Length % 4) % 4, '=') $payload = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($jwtPartPadded)) | ConvertFrom-Json Write-Host "Token tenant ID: $($payload.tid) | Target tenant ID: $($customer.TenantId)"
如果两者不匹配,将New-PartnerAccessToken的-Tenant参数改为$customer.TenantId(优先用租户ID而非域名,避免解析问题)。
4. 修复反钓鱼规则参数
确保规则关联的策略名正确,且域名参数为字符串数组:
# 创建反钓鱼策略 New-AntiPhishPolicy -Name "Brand New Policy" -AdminDisplayName "Brand New Policy" -EnableOrganizationDomainsProtection $true -Confirm:$false # 创建规则,关联正确的策略名,传入域名数组 New-AntiPhishRule -Name "Brand New Rule" -AntiPhishPolicy "Brand New Policy" -Enabled $false -RecipientDomainIs $domainNames -Confirm:$false
5. 权限配置确认
- 应用注册需在合作伙伴租户创建,添加以下应用权限(而非委派权限):
- Microsoft Graph:
Domain.Read.All(需客户租户管理员同意,或通过合作伙伴中心批量授权) - Exchange Online:
Exchange.ManageAsApp(用于管理反钓鱼策略)
- Microsoft Graph:
- 确保客户租户已通过管理员同意或合作伙伴批量授权,授予应用相应权限。
6. 备选方案:改用Get-MsolDomain获取域名
如果继续使用Get-MsolDomain,需在循环外以合作伙伴管理员身份登录MSOL,并确保应用或用户有相应权限:
# 循环外登录MSOL(用合作伙伴管理员凭据或服务主体凭据) Connect-MsolService -Credential $AppCredential # 循环内获取域名 $organizationDomains = Get-MsolDomain -TenantId $customer.TenantId | Select-Object -ExpandProperty Name
内容的提问来源于stack exchange,提问作者Targ4028
相关产品推荐
相关产品推荐

