使用Python3+Graph API检索Office365邮件时遇401错误求助
以下是针对你遇到问题的具体排查方向:
1. 检查Token请求的Scope是否正确
应用权限模式下,获取token必须使用https://graph.microsoft.com/.default作为scope,不能用委托权限的单个scope(比如Mail.Read)。你的MSAL代码里要确保是这样写的:
scope = ["https://graph.microsoft.com/.default"] result = app.acquire_token_for_client(scopes=scope)
如果scope不对,哪怕应用注册里配置了权限,拿到的token也不会包含对应的权限声明,直接导致401。
2. 验证Token的权限声明
把你拿到的access token放到JWT解析工具里查看,重点看roles字段是否包含需要的Mail权限(比如Mail.Read.All)。如果roles为空或者没有对应权限,大概率是应用权限未获得管理员同意——应用权限必须由全局管理员在Azure门户中点击“授予管理员同意”后,才会被包含在token里。
3. 确认API请求端点是否正确
应用权限模式下,不能用/me/messages端点,必须指定具体的用户ID或邮箱,正确的端点格式是:
GET https://graph.microsoft.com/v1.0/users/{user-email-or-id}/messages
/me仅适用于委托权限(有用户登录上下文),应用权限没有当前用户的概念,用这个端点会直接返回401。
4. 检查Token的受众(Audience)
解析token时看aud字段,必须是https://graph.microsoft.com。如果受众是其他值(比如Azure AD的其他API),Graph API会拒绝请求。
5. 核对应用注册配置
- 确保你的应用是后台服务/守护程序类型(无交互式登录),应用权限仅支持这种应用类型。
- 去Azure门户的应用注册页面,确认Mail类的应用权限(比如
Mail.Read.All)已经添加,并且状态显示“已授予[你的租户名]同意”。
6. 对比Graph Explorer的请求差异
Graph Explorer默认用委托权限,和你的应用权限流程完全不同。可以在Graph Explorer中切换到“应用权限”模式,用你的应用注册来测试相同的查询,看是否能成功——如果这里也失败,说明应用权限的配置有问题;如果成功,再对比脚本中的请求头、端点参数是否和Graph Explorer一致。
内容的提问来源于stack exchange,提问作者Bernietechy

