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 lagi semudah itu. Mewujudkan sambungan melalui OAuth2 kini memerlukan token akses terlebih dahulu. Ini memerlukan dua halangan untuk diatasi.

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

Setelah itu selesai, selebihnya mudah sahaja. Memandangkan barbushin/php-imap tidak menyokong oAuth2, anda boleh, sebagai contoh, mewujudkan sambungan menggunakan pustaka alternatif Webklex/php-imap (yang juga mempunyai kelebihan kerana tidak memerlukan modul PHP IMAP ).:

734a82898010e2fcb02c72c3cd9702c2

Tetapi perpustakaan yang tidak menyokong oAuth2 secara rasmi juga boleh digunakan dengan bantuan seperti proksi 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 mengikut prinsip yang sama seperti akses IMAP: di sini, juga, tiada cara untuk mengatasi oAuth2 sejak Pengesahan Asas telah dimatikan. Selepas menambah kebenaran "SMTP.SendAsApp" dalam pendaftaran apl Azure dan memberikan kebenaran pentadbir, penghantaran boleh dilakukan, contohnya 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