PowerShell+OAuth2调用Graph API获取Outlook邮件遇401授权错误
问题:Client Credentials流调用Graph API获取邮件返回401未授权
现象
- 用PowerShell通过Client Credentials流成功获取OAuth2令牌,解析后显示包含
Mail.Read等权限,但调用/v1.0/users/{user-id}/messages时返回401未授权 - 把API路径改成
/v1.0/users/{user-id}/能正常返回用户个人资料 - 直接用Graph Explorer生成的令牌替换代码中的令牌,就能正常获取邮件详情
令牌包含的权限
"roles": [ "Mail.ReadWrite", "Mail.ReadBasic.All", "Directory.Read.All", "User.Read.All", "Mail.Read", "Mail.Send", "Contacts.Read", "Mail.ReadBasic" ]
错误信息
Invoke-RestMethod: The remote server returned an error: (401) Unauthorized. At line:29 char:17 + ... rResponse = Invoke-RestMethod -Method Get -Uri $Uri -Headers $Headers ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
现有PowerShell代码
# 定义令牌请求地址和参数 $Uri = "https://login.microsoftonline.com/*********************************/oauth2/v2.0/token" $Body = @{ "grant_type" = "client_credentials" "client_id" = "*********************************" "client_secret" = "*********************************" "scope" = "https://graph.microsoft.com/.default" } $ContentType = "application/x-www-form-urlencoded" # 发送POST请求获取令牌 $Response = Invoke-RestMethod -Method Post -Uri $Uri -Body $Body -ContentType $ContentType # 输出访问令牌 Write-Output "Access Token: $($Response.access_token)" # 替换为目标用户的ID或用户主体名称 $Uri = "https://graph.microsoft.com/v1.0/users/*********************************/messages" # 定义请求头 $Headers = @{ "Authorization" = "Bearer $($Response.access_token)" } # 发送GET请求获取邮件 $UserResponse = Invoke-RestMethod -Method Get -Uri $Uri -Headers $Headers # 输出结果 Write-Output $UserResponse
原因分析与解决办法
核心问题
Client Credentials流是应用权限模式,只能使用Azure AD中给应用注册分配的应用权限,但当前令牌中的Mail.Read、Mail.ReadWrite等属于委托权限(需要用户登录授权的权限),这类权限无法在应用权限模式下生效。
而调用/users/{user-id}/能成功,是因为令牌中的User.Read.All是应用权限,符合Client Credentials流的要求。
解决步骤
添加正确的应用权限
登录Azure门户,进入「Azure Active Directory」→「应用注册」→找到你的应用→「API权限」→「添加权限」→选择「Microsoft Graph」→「应用权限」,添加Mail.Read.All(或Mail.ReadWrite.All,根据你的需求)。授予管理员同意
添加权限后,点击「授予管理员同意」(必须完成此操作,应用权限才能生效)。重新获取令牌并验证
重新运行PowerShell脚本获取令牌,解析后确认roles字段中包含Mail.Read.All。重新测试API调用
再次调用/v1.0/users/{user-id}/messages即可正常获取邮件。
补充说明
Graph Explorer使用的是委托权限流(需要用户登录授权),所以可以使用Mail.Read这类委托权限,这就是为什么替换Graph Explorer的令牌能正常工作的原因。
内容的提问来源于stack exchange,提问作者zsolti900
相关产品推荐
相关产品推荐

