Давно анонсированное — теперь реальность : Microsoft отключила аутентификацию по паролю для определенных протоколов в Exchange Online с сентября 2022 года в пользу oAuth2. Проблемы GitHub со многими библиотеками и сценариями резервного копирования ясно показывают, что переход застал многих администраторов врасплох. Ниже мы покажем, как вы можете продолжать получать доступ к содержимому вашего почтового ящика Exchange с помощью oAuth2 через PHP через IMAP.
С точки зрения безопасности шаг Microsoft очень правильный, но сложность программного доступа к ее электронной почте значительно возросла. Например, если вы используете широко используемую библиотеку barbushin/php-imap , доступ был следующим:
734a82898010e2fcb02c72c3cd9702c2
Это просто больше не работает. Для того, чтобы установить соединение через oAuth2, первая сложность — получить токен доступа. А для этого вам предстоит преодолеть два препятствия.
Azure Active Directory
Следующие шаги регистрируют новое приложение в Azure Active Directory.:













PowerShell
Теперь мы превращаем приложение в Майкрософт 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, также можно использовать с прокси-сервером, например simonrob/email-oauth2-proxy сделать работоспособным. После этого Скачать и установка через 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 подключиться через обычную Basic Auth (и любой установленный пароль). Если вы хотите запустить прокси как службу в фоновом режиме при запуске системы, вы можете использовать, например системад:
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
Отправка электронных писем
Любой, кто хочет отправлять электронные письма программным способом через Microsoft Exchange Online, также сталкивается с фундаментальным изменением: Microsoft отключила классическую аутентификацию по имени пользователя и паролю для SMTP в Exchange Online. То, что годами решалось всего несколькими строками кода, теперь требует обходного пути через OAuth2, включая регистрацию приложений в Azure Active Directory, сертификаты и управление токенами. Мы можем реализовать тот же подход для отправки электронных писем, помимо их получения.




Отправка SMTP-пакетов через Microsoft Exchange 365 осуществляется по тому же принципу, что и доступ по IMAP: после деактивации базовой аутентификации альтернативы OAuth2 нет. После добавления разрешения "SMTP.SendAsApp" в регистрацию приложения Azure и предоставления администратору подтверждения, отправку можно осуществлять, например, с помощью... PHPMailer Это реализовано. Вместо простой отправки имени пользователя и пароля, как раньше, аутентификация на SMTP-сервере теперь использует токен доступа. smtp.office365.com:
734a82898010e2fcb02c72c3cd9702c2
Дополнительные усилия по настройке могут поначалу показаться сложными, но в долгосрочной перспективе это окупается: аутентификация на основе OAuth2 значительно безопаснее, поскольку нет необходимости хранить пароли в открытом виде в конфигурационных файлах или скриптах, а токен доступа может быть ограничен по времени, а его права доступа можно контролировать с высокой точностью. Также стоит упомянуть библиотеку mailhelper , которая предлагает удобный API для получения и отправки электронных писем.