Truy cập bằng PHP vào Exchange / Office 365

Đã thông báo từ lâu - giờ đã thành hiện thực : Microsoft đã tắt xác thực bằng mật khẩu cho một số giao thức nhất định trong Exchange Online từ tháng 9 năm 2022 để ủng hộ oAuth2. Các vấn đề GitHub của nhiều thư việntập lệnh sao lưu cho thấy rõ ràng rằng việc chuyển đổi đã khiến nhiều quản trị viên ngạc nhiên. Dưới đây, chúng tôi chỉ ra cách bạn có thể tiếp tục truy cập nội dung hộp thư Exchange của mình với sự trợ giúp của oAuth2 qua PHP qua IMAP.


Từ quan điểm bảo mật, động thái của Microsoft là rất đúng đắn, nhưng mức độ phức tạp của việc truy cập theo chương trình vào các e-mail của hãng đã tăng lên khá nhiều. Ví dụ: nếu bạn sử dụng thư viện barbushin / php-imap được sử dụng rộng rãi, quyền truy cập được sử dụng như sau:

734a82898010e2fcb02c72c3cd9702c2

Nó chỉ không hoạt động nữa. Để thiết lập kết nối qua oAuth2, khó khăn đầu tiên là lấy mã thông báo truy cập. Và đối với điều này, bạn phải thực hiện hai trở ngại.

Azure Active Directory

Các bước sau đăng ký một ứng dụng mới trong Azure Active Directory:

Đăng nhập vào https://portal.azure.com
Mở "Azure Active Directory"
Chọn "Đăng ký ứng dụng" & "Đăng ký mới".
Sao chép "ID ứng dụng (Khách hàng)" (= ID khách hàng) & "ID thư mục (người thuê)" (= ID người thuê).
"Quyền API" & "Thêm quyền"
"API được tổ chức của tôi sử dụng" và "Office 365 Exchange Online"
"Quyền ứng dụng" & "IMAP.AccessAsApp"
Cấp sự đồng ý của quản trị viên
"Chứng chỉ & bí mật" & "Bí mật khách hàng" & "Bí mật khách hàng mới"
Chọn mô tả và đặt tính hợp lệ
Sao chép "ID bí mật" (Client Secret) vào khay nhớ tạm
Mở ứng dụng doanh nghiệp
Sao chép "ID đối tượng".

PowerShell

Bây giờ chúng tôi chuyển ứng dụng trong Microsoft PowerShell (Chế độ quản trị viên) và gán quyền cho từng hộp thư (<TENANTID>, <CLIENTID>, <OBJECTID>, <EMAIL> phải được thay thế trong từng trường hợp):

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

Khi bạn đã làm được điều đó, phần còn lại không phải là khoa học tên lửa. Vì barbushin / php-imap không hỗ trợ oAuth2, bạn có thể kết nối với thư viện thay thế Webklex / php-imap (cũng có ưu điểm là không yêu cầu mô-đun PHP IMAP ).:

734a82898010e2fcb02c72c3cd9702c2

Tuy nhiên, các thư viện không chính thức hỗ trợ oAuth2 cũng có thể được sử dụng với proxy như simonrob / email-oauth2-proxy làm cho nó hoạt động được. Sau đây Tải xuống và cài đặt thông qua python -m pip install -r requirements-no-gui.txt (Yêu cầu Python ≥3.6) bạn chỉnh sửa tệp emailproxy.config ví dụ như sau (thay thế lần này <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>

Sau đó, bạn khởi động proxy bằng python emailproxy.py --no-gui và bây giờ có thể truy cập IP không được mã hóa localhost trên cảng 1993 kết nối thông qua Basic Auth thông thường (và bất kỳ mật khẩu nào được đặt). Nếu bạn muốn khởi động proxy dưới dạng một dịch vụ ở chế độ nền khi khởi động hệ thống, bạn có thể sử dụng, ví dụ: hệ thống:

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

Nếu cần có kết nối được mã hóa, điều này cũng có thể thực hiện được - trước tiên, bạn tạo khóa riêng và chứng chỉ tự ký:

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

Sau đó, tài liệu tham khảo được thực hiện trong emailproxy.config hai tập tin này:

local_key_path = /path/to/key.pem
local_certificate_path = /path/to/cert.pem
Trở lại