Akses dengan PHP ke Exchange/Office 365

Lama diumumkan - kini realiti : Microsoft telah mematikan pengesahan melalui kata laluan untuk protokol tertentu dalam Exchange Online mulai September 2022 yang memihak kepada oAuth2. Isu GitHub bagi banyak perpustakaan dan skrip sandaran menjelaskan bahawa pertukaran itu mengejutkan ramai pentadbir. Di bawah kami menunjukkan cara bagaimana anda boleh terus mengakses kandungan peti mel Exchange anda dengan bantuan oAuth2 melalui PHP melalui IMAP.


Dari sudut pandangan keselamatan, langkah Microsoft adalah sangat betul, tetapi kerumitan akses program kepada e-melnya telah meningkat sedikit. Sebagai contoh, jika anda menggunakan perpustakaan barbushin/php-imap yang digunakan secara meluas, akses dahulu adalah seperti berikut:

734a82898010e2fcb02c72c3cd9702c2

Ia tidak berfungsi lagi. Untuk mewujudkan sambungan melalui oAuth2, kesukaran pertama adalah untuk mendapatkan token akses. Dan untuk ini anda perlu menghadapi dua halangan.

Direktori Aktif Azure

Langkah berikut mendaftarkan apl baharu dalam Azure Active Directory:

Log masuk ke https://portal.azure.com
Buka "Direktori Aktif Azure"
Pilih "Pendaftaran apl" & "Pendaftaran baharu".
Salin "ID Permohonan (Pelanggan)" (=ID Pelanggan) & "ID Direktori (Penyewa)" (=ID Penyewa).
"Kebenaran API" & "Tambah Kebenaran"
"API yang digunakan oleh organisasi saya" & "Office 365 Exchange Online"
"Kebenaran Aplikasi" & "IMAP.AccessAsApp"
Berikan kebenaran pentadbir
"Sijil & Rahsia" & "Rahsia Pelanggan" & "Rahsia Pelanggan Baharu"
Pilih perihalan dan tetapkan kesahihan
Salin "ID Rahsia" (Rahsia Pelanggan) ke papan keratan
Buka aplikasi perusahaan
Salin "ID Objek".

PowerShell

Sekarang kita menghidupkan aplikasi dalam Microsoft PowerShell (mod Pentadbir) dan berikan kebenaran kepada peti mel individu (<TENANTID>, <CLIENTID>, <OBJECTID>, <EMAIL> mesti diganti dalam setiap kes):

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
...

Sebaik sahaja anda melakukannya, selebihnya bukan sains roket. Memandangkan barbushin/php-imap tidak menyokong oAuth2, anda boleh menyambung dengan perpustakaan alternatif Webklex/php-imap (yang juga mempunyai kelebihan kerana tidak memerlukan modul PHP IMAP ).:

734a82898010e2fcb02c72c3cd9702c2

Walau bagaimanapun, perpustakaan yang tidak menyokong oAuth2 secara rasmi juga boleh digunakan dengan proksi seperti simonrob/email-oauth2-proxy jadikan ia boleh dilaksanakan. Selepas ini Muat turun dan pemasangan melalui python -m pip install -r requirements-no-gui.txt (Python ≥3.6 diperlukan) anda mengedit fail emailproxy.config cth. seperti berikut (menggantikan masa ini <TENANTID>, <CLIENTID>, <CLIENTSECRET> dan <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>

Kemudian anda mulakan proksi dengan python emailproxy.py --no-gui dan kini boleh pergi ke IP yang tidak disulitkan localhost di pelabuhan 1993 bersambung melalui Pengesahan Asas biasa (dan sebarang set kata laluan). Jika anda ingin memulakan proksi sebagai perkhidmatan di latar belakang apabila anda memulakan sistem, anda boleh menggunakan, sebagai contoh sistemd:

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

Jika sambungan yang disulitkan diperlukan, ini juga mungkin - untuk ini anda mula-mula membuat kunci peribadi dan sijil yang ditandatangani sendiri:

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

Kemudian rujukan dibuat dalam emailproxy.config dua fail ini:

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

Penghantaran e-mel

Sesiapa yang ingin menghantar e-mel secara pengaturcaraan melalui Microsoft Exchange Online juga menghadapi perubahan asas: Microsoft telah melumpuhkan pengesahan nama pengguna dan kata laluan klasik untuk SMTP dalam Exchange Online. Apa yang dicapai hanya dengan beberapa baris kod selama bertahun-tahun kini memerlukan lencongan melalui OAuth2 – termasuk pendaftaran aplikasi dalam Azure Active Directory, sijil dan pengurusan token. Kita boleh melaksanakan pendekatan yang sama untuk menghantar e-mel, selain menerimanya.

"Kebenaran API" & "Tambah Kebenaran"
"API yang digunakan oleh organisasi saya" & "Office 365 Exchange Online"
"Kebenaran aplikasi" & "SMTP.SendAsApp"
Berikan kebenaran pentadbir

Penghantaran SMTP melalui Microsoft Exchange 365 mengikuti prinsip yang sama seperti akses IMAP: Sejak penyahaktifan Pengesahan Asas, tiada alternatif kepada OAuth2. Selepas menambah kebenaran "SMTP.SendAsApp" dalam pendaftaran aplikasi Azure dan memberikan kelulusan pentadbir, penghantaran boleh dilakukan, contohnya, dengan... PHPMailer Ini dilaksanakan. Daripada hanya menghantar nama pengguna dan kata laluan seperti sebelumnya, pengesahan terhadap pelayan SMTP kini menggunakan token akses. smtp.office365.com:

734a82898010e2fcb02c72c3cd9702c2

Usaha persediaan tambahan mungkin pada mulanya kelihatan sukar, tetapi ia berbaloi dalam jangka masa panjang: Pengesahan berasaskan OAuth2 jauh lebih selamat, kerana tiada kata laluan teks biasa perlu disimpan dalam fail konfigurasi atau skrip – dan token akses juga boleh dihadkan masa dan kebenarannya dikawal dengan tepat. Turut perlu disebut di sini ialah pustaka mailhelper , yang menawarkan API yang mudah untuk menerima dan menghantar e-mel.

Belakang