使用 PHP 访问 Exchange/Office 365

长期宣布-现在成为现实:从 2022 年 9 月起,Microsoft 已关闭 Exchange Online 中某些协议的密码身份验证,转而使用 oAuth2。 许多备份脚本的 GitHub 问题清楚地表明,这种转换让许多管理员感到意外。 下面我们展示了一种方法,您可以如何在 oAuth2 的帮助下通过 PHP 通过 IMAP 继续访问您的 Exchange 邮箱的内容。


从安全的角度来看,微软的举动是非常正确的,但是以编程方式访问其电子邮件的复杂性增加了不少。 例如,如果你使用广泛使用的barbushin/php-imap 库,访问曾经如下:

734a82898010e2fcb02c72c3cd9702c2

它只是不再起作用了。 为了通过oAuth2建立连接,第一个困难是获取访问令牌。 为此,您必须克服两个障碍。

Azure 活动目录

以下步骤在 Azure Active Directory 中注册新应用:

登录到https://portal.azure.com
打开“Azure 活动目录”
选择“应用注册”和“新注册”。
复制“应用程序 ID(客户端)”(=客户端 ID)和“目录 ID(租户)”(=租户 ID)。
“API 权限”和“添加权限”
“我的组织使用的 API”和“Office 365 Exchange Online”
“应用程序权限”和“IMAP.AccessAsApp”
授予管理员同意
“证书和机密” & “客户机密” & “新客户机密”
选择描述并设置有效期
将“Secret ID”(客户端密码)复制到剪贴板
开放企业应用
复制“对象 ID”。

电源外壳

现在我们将应用程序转入 微软PowerShell (管理员模式)并为各个邮箱分配权限(<TENANTID>, <CLIENTID>, <OBJECTID>, <EMAIL> 必须在每种情况下更换):

Install-Module -Name ExchangeOnlineManagement
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -Organization <TENANTID>

New-ServicePrincipal -AppId <CLIENTID> -ServiceId <OBJECTID>
Add-MailboxPermission -Identity "<EMAIL>" -User <OBJECTID> -AccessRights FullAccess
...

一旦你做到了,剩下的就不是火箭科学了。 由于barbushin/php-imap不支持 oAuth2,因此您可以使用替代库Webklex/php-imap连接(它还有不需要PHP IMAP 模块的优点)。:

734a82898010e2fcb02c72c3cd9702c2

但是,官方不支持 oAuth2 的库也可以与代理一起使用,例如 西蒙罗布/电子邮件-oauth2-代理 使其可行。 在这之后 下载 并通过安装 python -m pip install -r requirements-no-gui.txt (需要 Python ≥3.6)您编辑文件 emailproxy.config 例如如下(更换本次 <TENANTID>, <CLIENTID>, <CLIENTSECRET><EMAIL>):

[Server setup]

[IMAP-1993]
local_address = localhost
server_address = outlook.office365.com
server_port = 993

[Account setup]

[<EMAIL>]
token_url = https://login.microsoftonline.com/<TENANTID>/oauth2/v2.0/token
oauth2_scope = https://outlook.office365.com/.default
redirect_uri = http://localhost:8080
client_id = <CLIENTID>
client_secret = <CLIENTSECRET>

然后你启动代理 python emailproxy.py --no-gui 现在可以访问未加密的 IP localhost 在港口 1993 通过常规基本身份验证(和任何密码集)进行连接。 如果要在启动系统时将代理作为服务在后台启动,可以使用,例如 系统:

sudo systemctl edit --force --full emailproxy.service

[Unit]
Description=Email OAuth 2.0 Proxy
[Service]
ExecStart=/usr/bin/python /path/to/emailproxy.py --no-gui
Restart=always
[Install]
WantedBy=multi-user.target

sudo systemctl enable emailproxy.service --now
sudo systemctl status emailproxy.service
sudo systemctl start emailproxy.service

如果需要加密连接,这也是可能的 - 为此您首先创建一个私钥和一个自签名证书:

openssl genrsa -out key.pem 3072
openssl req -new -x509 -key key.pem -out cert.pem -days 360

然后参考在 emailproxy.config 这两个文件:

local_key_path = /path/to/key.pem
local_certificate_path = /path/to/cert.pem
背部