Доступ за допомогою PHP до Exchange/Office 365

Давно оголошенетепер реальність : з вересня 2022 року Microsoft вимкнула автентифікацію за паролем для певних протоколів в Exchange Online на користь 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»
Надайте згоду адміністратора
«Сертифікати та секрети» & «Секрети клієнта» & «Секрети нового клієнта»
Виберіть опис і встановіть термін дії
Скопіюйте «Секретний ідентифікатор» (Client Secret) у буфер обміну
Відкриті корпоративні програми
Скопіюйте «ID об’єкта».

PowerShell

Тепер ми перетворюємо додаток у Microsoft 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-проксі зробити це працездатним. Після цього Завантажити і встановлення через 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 підключитися через звичайну базову авторизацію (і будь-який встановлений пароль). Якщо ви хочете запустити проксі як службу у фоновому режимі під час запуску системи, ви можете використовувати, наприклад systemd:

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