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

Python使用OAuth2认证Microsoft SMTP发信报535 5.7.3错误如何解决

问题根因定位

你遇到的535 5.7.3认证失败主要来自以下几个高频错误点,按照优先级排序:

  • 权限配置类型错误:你在AAD应用中配置的SMTP.Send权限如果是「应用程序权限」而非「委托权限」,即便已经授权也无法通过SMTP OAuth认证,Office 365 SMTP OAuth仅支持委托权限场景,且必须由租户管理员完成权限同意。
  • Exchange Online租户级配置限制:即使单个邮箱开启了SMTP权限,租户默认可能禁用了legacy协议的OAuth访问能力,需要在Exchange管理中心开启对应策略。
  • SMTP指令调用顺序/参数错误:你现有代码的SMTP指令流程存在两处错误:
    1. XOAUTH2认证必须使用EHLO指令而非HELO,HELO不支持扩展认证协议协商
    2. 指令执行顺序错误:正确流程应为「建立连接→EHLO→开启STARTTLS→再次EHLO→发起认证」,你现有代码在STARTTLS之后才首次发起HELO,不符合协议要求
  • Token发送格式错误:你编码后的XOAUTH2 token发送时未追加\r\n结束符,部分Office 365节点会将未正确结束的请求视为非法包直接拒绝。

可行解决方案

步骤1:修正AAD应用权限配置

  • 进入AAD应用注册页的「API权限」界面,删除原有SMTP.Send权限
  • 重新添加权限:选择「Office 365 Exchange Online」→「委托权限」→搜索勾选SMTP.Send
  • 点击「授予管理员同意」完成全局授权

步骤2:检查Exchange Online租户配置

  • 进入Exchange管理中心,确认租户级「已启用安全默认值」设置为关闭,安全默认值会直接拦截所有legacy协议的OAuth请求
  • 执行Exchange Online PowerShell命令确认SMTP AUTH策略:
Get-TransportConfig | Format-List SmtpClientAuthenticationDisabled

如果返回值为True,执行命令开启:

Set-TransportConfig -SmtpClientAuthenticationDisabled $False

步骤3:修正SMTP认证代码

替换你的MicrosoftSMTP类和调用逻辑为以下版本:

import smtplib
import base64

class MicrosoftSMTP(smtplib.SMTP):
    def __init__(self, host="smtp.office365.com", port=587, **kwargs):
        super().__init__(host=host, port=port, **kwargs)
        self.set_debuglevel(True)

    @staticmethod
    def encode_auth_token(username, token):
        auth_str = f"user={username}\x01auth=Bearer {token}\x01\x01"
        return base64.b64encode(auth_str.encode('utf-8')).decode('ascii')

    def authenticate(self, username, token):
        # 首次EHLO协商扩展能力
        code, msg = self.ehlo()
        if code != 250:
            raise Exception(f"EHLO failed: {msg.decode()}")
        
        # 开启TLS后再次EHLO
        code, msg = self.starttls()
        if code != 220:
            raise Exception(f"STARTTLS failed: {msg.decode()}")
        
        code, msg = self.ehlo()
        if code != 250:
            raise Exception(f"Post-TLS EHLO failed: {msg.decode()}")

        # 发起XOAUTH2认证
        code, msg = self.docmd("AUTH", "XOAUTH2")
        if code != 334:
            raise Exception(f"Auth init failed: {msg.decode()}")

        # 发送token,自动追加\r\n结束符
        code, msg = self.docmd(self.encode_auth_token(username, token))
        if code != 235:
            raise Exception(f"Auth failed: {msg.decode()}")

调用逻辑简化为:

@app.route("/send_to_self")
def send_to_self():
    token = _get_token_from_cache(app_config.SCOPE)
    if not token:
        return redirect(url_for("login"))

    connection = MicrosoftSMTP()
    try:
        connection.authenticate(
            token["id_token_claims"]["preferred_username"],
            token["access_token"],
        )
        # 此处添加邮件发送逻辑
        # connection.sendmail(from_addr, to_addrs, msg.as_string())
    finally:
        connection.quit()

    return render_template(
        "send_to_self.html",
        data=token,
        data_session=session["flow"],
        data_user=session["user"],
    )

步骤4:校验Token有效性

如果上述步骤执行后仍报错,将获取到的access_token粘贴到JWT解析工具中解析,确认aud字段值为https://outlook.office.com,如果是Graph API的受众则说明Scope配置错误,需确认请求Scope为https://outlook.office.com/SMTP.Send。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 13:45:02