使用MS Graph调用邮箱收件箱消息接口返回403权限错误的排查求助
问题描述
为了自动处理我的微软账户邮件,我注册了名为
NameOfMyRegisteredApplication的应用,给它分配了所有Microsoft Graph读取权限,随后在Ubuntu 24.10系统搭配Python 3.12环境下运行了以下测试代码:def test(): # 以下三个字符串是微软应用注册时提供的: sClntId = '????????-????-????-????-????????????' # 应用(客户端)ID sClntCrd = '??????????????????????????????????' # 客户端密钥/密码 sObjId = '????????-????-????-????-????????????' # 目录(租户)ID oCCA = ConfidentialClientApplication( client_id=sClntId, client_credential=sClntCrd, authority=F'https://login.microsoftonline.com/{sObjId}' ) oScps = ['https://graph.microsoft.com/.default'] # Microsoft Graph 权限范围 oRslt = oCCA.acquire_token_for_client(oScps) strTkn = oRslt['access_token'] ''' 解码后的access_token包含以下字段: { "aud":"https://graph.microsoft.com", "iss":"https://sts.windows.net/sObjId/",// 对应上方的sObjId "iat":t,// 时间戳(秒) "nbf":t, "exp":t+3900, "aio":"????????????????????", "app_displayname":"NameOfMyRegisteredApplication" "appid":"sClntId", "appidacr":"1", "idp":"https://sts.windows.net/sObjId/", "idtyp":"app", "oid":"????????-????-????-????-????????????", "rh":"??????????????????????????????????????????", "sub":"????????-????-????-????-????????????", "tenant_region_scope":"NA", "tid":"sObjId", "uti":"???????????????????????????? ", "ver":"1.0", "wids":["????????-????-????-????-????????????"], "xms_ftd":"????????????????????", "xms_idrel":"i jk", "xms_rd":"?????????????????????????????", "xms_tcdt":dddddddddd } ''' sGrfUrl = 'https://graph.microsoft.com/v1.0' sUserId = '????????-????-????-????-????????????' # 我的邮箱账户ID sUrl = F'{sGrfUrl}/users/{sUserId}/mailFolders/Inbox/Messages' sResp = requests.get( sUrl, headers={'Authorization':F'Bearer {strTkn}', 'Content-Type':'application/json'} ) print(sResp) # 输出 <Response [403]> return;请问我的脚本中缺少了什么配置或步骤?提前感谢解答!
排查与解决方案
我帮你梳理了几个最可能触发403权限错误的原因,按优先级逐一排查:
权限类型混淆:误用委托权限而非应用权限
你采用的是客户端凭证流(Client Credential Flow),即应用以自身身份独立访问Microsoft Graph,这种认证方式仅支持应用权限(Application Permissions),无法使用委托权限(Delegated Permissions)。如果你在Azure AD应用注册中添加的是委托权限,哪怕是读取类权限,生成的token也没有访问用户邮箱的权限。- 解决方法:登录Azure Portal,找到你的应用注册,进入「API权限」页面,删除现有的委托权限,添加Microsoft Graph下的应用权限(比如
Mail.Read,该权限允许应用读取所有用户的邮箱内容)。
- 解决方法:登录Azure Portal,找到你的应用注册,进入「API权限」页面,删除现有的委托权限,添加Microsoft Graph下的应用权限(比如
未完成管理员同意
绝大多数应用权限需要全局管理员或Exchange管理员授予管理员同意,否则即使你添加了权限,生成的token也不会包含对应的权限声明,自然会返回403。- 解决方法:在「API权限」页面,点击「授予管理员同意」按钮,等待页面显示“已授予”的绿色标识后,重新获取token并测试接口。
Token未包含目标权限
从你提供的token解码结果来看,里面没有roles字段——客户端凭证流的权限声明会存在于roles字段中(委托权限则在scp字段),这说明你的token根本没有获取到邮箱访问权限。你可以用JWT解析工具检查token,确认是否存在roles字段且包含Mail.Read权限。权限范围不足
确保你添加的应用权限能够覆盖需求:比如要读取收件箱完整消息,Mail.Read权限足够;如果仅添加了Mail.ReadBasic,只能读取邮件主题、发件人等基础信息,不过一般不会直接导致403,但仍建议确认权限的正确性。用户ID准确性验证
核对sUserId是否为正确的用户标识:可以是用户的Object ID,也可以是用户的UPN(比如yourname@yourdomain.com)。如果ID错误,可能返回404,但某些场景下也会触发403,建议与Azure AD中用户的信息进行核对。
另外,你的代码逻辑本身没有问题:客户端凭证流使用https://graph.microsoft.com/.default作为scope是正确的,它会自动包含你为应用配置的所有应用权限。
优先从权限类型和管理员同意这两点入手排查,这是这类403错误最常见的根源。
内容来源于stack exchange

