如何在不关闭安全默认设置的情况下从Microsoft Workspace邮箱发邮件?
解决Microsoft Workspace邮箱SMTP认证失败(安全默认策略限制)的方案
问题原因
你遇到的535 5.7.139错误,是因为组织启用了安全默认设置——这类设置会禁用传统的「用户名+密码」SMTP认证,强制使用更安全的认证方式,所以直接用nodemailer的密码登录方式行不通。
最佳安全方案:使用Microsoft Graph API
完全可行,这是微软官方推荐的现代、安全的实现方式,步骤如下:
1. 前置配置(Azure AD应用注册)
- 登录Azure门户,创建新的应用注册
- 为该应用添加Mail.Send类型的应用权限(注意是应用权限,而非委托权限,适配后端无交互场景)
- 由管理员授予该权限的同意
- 生成并保存客户端密码(密钥)、应用ID、租户ID
2. Node.js代码实现
使用@microsoft/microsoft-graph-client和@azure/msal-node库完成开发:
const { Client } = require('@microsoft/microsoft-graph-client'); const { ClientCredentialAuthenticationProvider } = require('@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials'); const { ConfidentialClientApplication } = require('@azure/msal-node'); async function sendMailWithGraph() { // 配置MSAL客户端 const confidentialClientConfig = { auth: { clientId: '你的应用ID', tenantId: '你的租户ID', clientSecret: '你的客户端密钥' } }; const cca = new ConfidentialClientApplication(confidentialClientConfig); // 创建认证提供者 const authProvider = new ClientCredentialAuthenticationProvider(cca, { scopes: ['https://graph.microsoft.com/.default'] }); // 初始化Graph客户端 const client = Client.initWithMiddleware({ authProvider }); // 发送邮件 try { const response = await client.api('/me/sendMail') .post({ message: { subject: 'subject', body: { contentType: 'Text', content: 'Welcome aboard...!' }, toRecipients: [ { emailAddress: { address: 'to@example.com' } } ] }, saveToSentItems: true }); return response; } catch (error) { console.error('发送邮件失败:', error); throw error; } }
补充说明
- 应用权限模式下,调用
/me/sendMail会以应用身份发送邮件;若需要指定特定发件邮箱,可在请求体中添加from参数,同时确保应用拥有对应邮箱的发送权限 - 该方式无需用户交互,完全适配后端服务场景,且符合安全默认策略要求
替代方案:SMTP+OAuth2认证(不推荐)
如果坚持使用SMTP协议,可配置OAuth2认证,但步骤繁琐且微软对SMTP的支持正在弱化:
- 注册Azure AD应用,添加SMTP.Send委托权限
- 获取用户刷新令牌,在nodemailer中配置OAuth2认证参数
- 此方式需要用户手动授权,不适用于无交互的后端服务
总结
优先选择Microsoft Graph API,它不仅完全兼容组织的安全默认策略,还支持更丰富的邮件功能(如HTML邮件、附件、日历邀请等),是当前最安全且符合微软生态规范的实现方式。
内容的提问来源于stack exchange,提问作者Schnitzler
相关产品推荐
相关产品推荐

