长期宣布-现在成为现实:从 2022 年 9 月起,Microsoft 已关闭 Exchange Online 中某些协议的密码身份验证,转而使用 oAuth2。 许多库和备份脚本的 GitHub 问题清楚地表明,这种转换让许多管理员感到意外。 下面我们展示了一种方法,您可以如何在 oAuth2 的帮助下通过 PHP 通过 IMAP 继续访问您的 Exchange 邮箱的内容。
从安全的角度来看,微软的举动是非常正确的,但是以编程方式访问其电子邮件的复杂性增加了不少。 例如,如果你使用广泛使用的barbushin/php-imap 库,访问曾经如下:
734a82898010e2fcb02c72c3cd9702c2
它只是不再起作用了。 为了通过oAuth2建立连接,第一个困难是获取访问令牌。 为此,您必须克服两个障碍。
Azure 活动目录
以下步骤在 Azure Active Directory 中注册新应用:
电源外壳
现在我们将应用程序转入 微软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