获取O365 SMTP刷新令牌的OAuth2范围及PHP配置方法
问题描述
我们公司为员工及3个部门(服务、支持、报告)分配邮箱,格式如 <employee_name>@<company_name>.de 或 support@<company_name>.de。现有程序通过Windows任务计划启动脚本,调用PHPMailer以SMTP(主机:smtp.office365.com)从部门邮箱发邮件,执行时无需微软用户登录。
现在需要从SMTP基本认证切换至OAuth2,已在Azure门户主租户(管理员账号:<boss_name>@<company_name>.de)注册Web应用“PHPMailer”,并配置了应用权限 Mail.Send 和 User.Read。
在使用PHPMailer自带的get_oauth_token.php获取刷新令牌时,发现示例中的微软scope为 ['wl.imap', 'wl.offline_access'],存在以下疑问:
- 该示例scope是否需要针对SMTP场景修改?
- scope的命名规则,比如
offline_access与wl.offline_access的区别,以及wl.前缀的含义? - 查阅官方文档后发现现有PHPMailer Azure OAuth2指南仅针对委派权限场景(需要用户登录),不适用于我们的应用权限无登录场景,因此需要明确O365 SMTP应用权限场景下所需的scope,以及如何配置
get_oauth_token.php。
解决方案
1. O365 SMTP应用权限场景的Scope说明
- 应用权限(无用户交互)场景下,不需要指定具体的SMTP相关scope字符串,只需使用微软Graph的特殊scope:
https://outlook.office365.com/.default。这个scope表示直接使用你在Azure门户中预先授予该应用的所有应用权限(你已配置Mail.Send,完全满足SMTP发信需求)。 - 关于
wl.前缀:这是旧版Windows Live API的遗留命名,当前微软Graph API已不再使用该前缀,offline_access是标准的scope(用于委派权限场景获取刷新令牌),但在应用权限场景下不需要这个scope,因为客户端凭证流无需用户刷新令牌。
2. get_oauth_token.php的配置调整
原脚本默认适配委派权限(需要用户登录),要适配应用权限场景,需修改为客户端凭证流,无需浏览器登录交互:
- 替换原示例中的scope数组:
$scope = ['https://outlook.office365.com/.default']; - 注释掉原脚本中涉及授权码流、浏览器跳转的代码,改用客户端ID和密钥直接请求令牌:
$oauth = new PHPMailer\PHPMailer\OAuth(); $oauth->setClientId('你的Azure应用客户端ID'); $oauth->setClientSecret('你的Azure应用客户端密钥'); $oauth->setTokenURL('https://login.microsoftonline.com/你的租户ID/oauth2/v2.0/token'); // 获取访问令牌 $token = $oauth->getAccessToken('client_credentials'); - 注意:应用权限场景下,不需要通过浏览器打开脚本获取刷新令牌,客户端凭证流会返回可定期刷新的访问令牌,全程无需用户参与。
3. 额外配置验证
- 确认Azure应用已授予
Mail.Send应用权限(而非委派权限),且已完成管理员同意(在Azure门户的应用权限页面点击“授予管理员同意”)。 - PHPMailer的SMTP核心配置保持不变:
$mail->isSMTP(); $mail->Host = 'smtp.office365.com'; $mail->SMTPAuth = true; $mail->SMTPSecure = 'tls'; $mail->Port = 587; // 将获取到的令牌设置到PHPMailer $mail->setOAuth($oauth);
内容的提问来源于stack exchange,提问作者biberman
相关产品推荐
相关产品推荐

