You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python调用Microsoft Graph API发邮件遇权限拒绝及令牌缓存问题

问题描述

使用Python代码调用Microsoft Graph API发送邮件时出现权限拒绝错误,但Postman中可成功发送,不清楚哪里配置缺失。

代码示例

import json
import msal
import requests

client_id = '6c762**************'
client_secret = 'F-S**************************'
tenant_id = 'e*****************************'
authority = f"https://login.microsoftonline.com/{tenant_id}"

app = msal.ConfidentialClientApplication(
    client_id=client_id,
    client_credential=client_secret,
    authority=authority)

scopes = ["https://graph.microsoft.com/.default"]

result = None
result = app.acquire_token_silent(scopes, account=None)

if not result:
    print(
        "No suitable token exists in cache. Let's get a new one from Azure Active Directory.")
    result = app.acquire_token_for_client(scopes=scopes)

# if "access_token" in result:
#     print("Access token is " + result["access_token"])


if "access_token" in result:
    userId = "support@****.com"
    endpoint = f'https://graph.microsoft.com/v1.0/users/{userId}/sendMail'
    toUserEmail = "hi****@gmail.com"

    email_msg = {'Message': {'Subject': "Test Sending Email from Python",
                             'Body': {'ContentType': 'Text', 'Content': "This is a test email."},
                             'ToRecipients': [{'EmailAddress': {'Address': toUserEmail}}]
                             },
                 'SaveToSentItems': 'true'}
    r = requests.post(endpoint,
                      headers={'Authorization': 'Bearer ' + result['access_token']}, json=email_msg)
    if r.ok:
        print('Sent email successfully')
    else:
        print(r.json())
else:
    print(result.get("error"))
    print(result.get("error_description"))
    print(result.get("correlation_id"))

错误信息

缓存中无合适令牌,将从Azure Active Directory获取新令牌。
{'error': {'code': 'ErrorAccessDenied', 'message': '访问被拒绝,请检查凭据并重试。'}}

排查与解决

Postman能成功发送,说明API本身可用,问题出在Python代码的权限配置或认证环节,按以下步骤排查:

  • 确认权限类型与配置:代码用的是客户端凭证模式(acquire_token_for_client),必须在Azure AD应用注册中配置应用权限的Mail.Send,并且完成管理员同意。如果Postman用的是委派权限(比如账号密码登录),两种模式权限要求不同,这是核心差异点。
  • 检查权限生效状态:登录Azure AD后台,找到你的应用注册,进入“权限”页面,确保Mail.Send(应用权限)的状态是“已授予管理员同意”。
  • 验证令牌权限:获取到access_token后,解析令牌查看roles字段是否包含Mail.Send。如果没有,说明权限配置未生效,重新配置后等待几分钟再测试。
  • 核对凭证信息:确保代码中的client_id、client_secret、tenant_id和Postman中使用的完全一致,无字符遗漏或输入错误。
  • 确认用户账号有效性:代码中指定的userId(support@****.com)必须是租户内的有效邮箱账号,且应用权限允许代表该账号发送邮件。

内容的提问来源于stack exchange,提问作者Hietsh Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 03:56:16