Доступ с PHP к Exchange/Office 365

Давно анонсированноетеперь реальность : Microsoft отключила аутентификацию по паролю для определенных протоколов в Exchange Online с сентября 2022 года в пользу oAuth2. Проблемы GitHub со многими библиотеками и сценариями резервного копирования ясно показывают, что переход застал многих администраторов врасплох. Ниже мы покажем, как вы можете продолжать получать доступ к содержимому вашего почтового ящика Exchange с помощью oAuth2 через PHP через IMAP.


С точки зрения безопасности шаг Microsoft очень правильный, но сложность программного доступа к ее электронной почте значительно возросла. Например, если вы используете широко используемую библиотеку barbushin/php-imap , доступ был следующим:

734a82898010e2fcb02c72c3cd9702c2

Это просто больше не работает. Для того, чтобы установить соединение через oAuth2, первая сложность — получить токен доступа. А для этого вам предстоит преодолеть два препятствия.

Azure Active Directory

Следующие шаги регистрируют новое приложение в Azure Active Directory.:

Войти в https://portal.azure.com
Откройте «Azure Active Directory».
Выберите «Регистрации приложений» и «Новая регистрация».
Скопируйте «Идентификатор приложения (клиент)» (= Идентификатор клиента) и «Идентификатор каталога (клиент)» (= Идентификатор клиента).
«Разрешения API» и «Добавить разрешение»
«API, используемые моей организацией» и «Office 365 Exchange Online»
«Разрешения для приложений» и «IMAP.AccessAsApp»
Предоставить согласие администратора
"Сертификаты и секреты" и "Клиентские секреты" и "Новый клиентский секрет"
Выберите описание и установите срок действия
Скопируйте «Secret ID» (Client Secret) в буфер обмена
Открытые корпоративные приложения
Скопируйте «Идентификатор объекта».

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
Назад