如何配置Python的SMTPHandler通过Microsoft 365发送邮件?
问题
现有一段在Redhat Linux上运行的Python 3.6代码,原本通过本地邮件服务器发送邮件正常,现在需要修改为连接Microsoft云邮件服务器(Office 365直连中继)。
原代码:
import logging.handlers # mail server = ourcompanynamehere.mail.protection.outlook.com # old mail server = mail.ourcompanynamehere.com.au smtp_handler = logging.handlers.SMTPHandler(mailhost=("mail.ourcompanynamehere.com.au", 25), fromaddr="coolcat@ourcompanynamehere.com.au", toaddrs="coolcat@ourcompanynamehere.com.au", subject=u"Email error test!") logger = logging.getLogger() logger.addHandler(smtp_handler) def foo(): raise Exception("Foo Bar") try: foo() except Exception as e: logger.exception('Unhandled Exception')
运维提供的Office 365直连中继配置:
已为直连发送配置Office 365中继,请将应用、打印机或服务配置为以下邮件中继设置。关闭Exchange服务器前需完成所有服务更新。该中继仅支持来自外部IP xx.xx.xx.xx的本地环境。
设备或应用设置 值
服务器/智能主机 ourcompanynamehere.mail.protection.outlook.com
端口 25
TLS/StartTLS 启用
邮箱地址 任意Microsoft 365或Office 365已验证域名下的邮箱地址,无需对应邮箱。
仅替换服务器名称后发送失败,尝试过设置secure为空元组、添加用户名密码、延长超时时间均无效,不清楚如何正确配置StartTLS。
解决方案
Office 365的直连中继要求启用StartTLS,而logging.handlers.SMTPHandler默认不会主动开启加密连接,需要通过secure参数触发StartTLS握手,同时因为是IP白名单验证,不需要提供用户名密码凭证。
修改后的代码如下:
import logging.handlers # Office 365中继服务器配置 smtp_handler = logging.handlers.SMTPHandler( mailhost=("ourcompanynamehere.mail.protection.outlook.com", 25), fromaddr="coolcat@ourcompanynamehere.com.au", # 需为已验证域名下的邮箱 toaddrs="coolcat@ourcompanynamehere.com.au", subject="Email error test!", secure=(), # 空元组触发StartTLS加密 timeout=10 # 延长超时时间,避免连接超时 ) logger = logging.getLogger() logger.setLevel(logging.ERROR) # 确保日志级别足够触发发送 logger.addHandler(smtp_handler) def foo(): raise Exception("Foo Bar") try: foo() except Exception as e: logger.exception('Unhandled Exception')
关键修改点说明:
- 替换mailhost:使用运维提供的
ourcompanynamehere.mail.protection.outlook.com,端口保持25 - 添加
secure=():这个参数会让SMTPHandler在连接后调用starttls()方法,启用TLS加密,符合Office 365的要求 - 设置timeout:延长超时时间避免网络延迟导致的连接失败
- 确认日志级别:默认logger级别是WARNING,
logger.exception属于ERROR级别,需要确保logger的级别不高于ERROR(比如设置为logging.ERROR),否则日志不会被发送
额外注意事项:
- 确认运行代码的服务器IP在运维提供的白名单
xx.xx.xx.xx范围内,这是Office 365中继允许发送的前提 fromaddr必须是Microsoft 365已验证域名下的邮箱地址,不需要实际存在对应邮箱- 不要添加
credentials参数,因为该中继是基于IP白名单验证,不需要用户名密码认证
内容的提问来源于stack exchange,提问作者Craig Smith
相关产品推荐
相关产品推荐

