Let administrators link Microsoft accounts whose UPN differs from mail
Some checks are pending
CI / PHP lint (7.4) (pull_request) Waiting to run
CI / PHP lint (8.0) (pull_request) Waiting to run
CI / PHP lint (8.1) (pull_request) Waiting to run
CI / PHP lint (8.2) (pull_request) Waiting to run
CI / PHP lint (8.3) (pull_request) Waiting to run
CI / PHP lint (8.4) (pull_request) Waiting to run
CI / WordPress Coding Standards (pull_request) Waiting to run
CI / WordPress.org Plugin Check (pull_request) Waiting to run

Privileged accounts are never linked through the settable mail
attribute. Two new ways make that workable when UPN and e-mail differ:

- "Link Microsoft account" on the profile screen: the signed-in user
  (nonce, same browser via the state cookie, same user at the callback)
  signs in with Microsoft once and binds that identity. Existing links
  can only be removed by an administrator; an object ID bound elsewhere
  is refused.
- "Assigned Microsoft account (UPN)" per user, editable by
  administrators, used by sign-in and user sync; with an option to
  remove a link.

Sign-in now finds accounts by bound object ID first, then by assigned
UPN, then by e-mail, so linked users sign in whatever their addresses.

Also: third-audit report (docs/security-audit.md section 7), README
section on linking administrator accounts, translations, tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Friederich Loheide 2026-09-24 03:57:45 +00:00
parent 9b893e42bc
commit 81b3a74ae5
12 changed files with 1583 additions and 995 deletions

View file

@ -103,6 +103,10 @@ Signing in never creates users: they must already exist in WordPress, linked by
With the user sync, a WordPress account whose Microsoft 365 account is disabled or deleted can be deactivated (no sign-in of any kind, sessions ended) or deleted (content reassigned to a user you pick). If the Microsoft 365 account is enabled again, an account deactivated by the sync is reactivated automatically. Administrators that existed before the sync are never deactivated or deleted automatically.
= Our administrators' user principal name differs from their e-mail address. How do they sign in? =
Administrator accounts are never linked through the Microsoft "mail" attribute, because any user or Exchange administrator of the tenant can set it. Either the person signs in once with the password and clicks "Link Microsoft account" on the profile page, or an administrator enters the person's user principal name under "Assigned Microsoft account (UPN)" in the WordPress profile. After that the account is found through the Microsoft object ID.
= Which Microsoft Graph permissions does the user sync need? =
The application permission `User.Read.All` with admin consent, plus `GroupMember.Read.All` when you limit the sync to groups or map groups to roles. A tenant GUID must be configured on the Connection tab.
@ -156,6 +160,7 @@ The settings, cached data, the sync report and schedule, stored profile photos a
* New: "Microsoft 365" column, deactivate/reactivate row actions and a read-only Microsoft 365 section on the profile screen.
* New: `wp m365-login sync [--dry-run]` WP-CLI command and scheduled sync via WP-Cron.
* New: excluded Entra groups their members can never sign in with Microsoft.
* New: "Link Microsoft account" on the profile page and an administrator-assigned Microsoft account (UPN) per user; linked accounts are found by their Microsoft object ID.
* Fix: failed Microsoft sign-ins (e.g. expired secret, group not allowed) ended in a PHP fatal error instead of the error message.
* Security: fixes from a full security audit see docs/security-audit.md (button-only bypasses via XML-RPC/REST, administrator linking, multisite settings restricted to super admins, deactivation hardening, and more).
* Fix: generating or removing the certificate in the settings did not keep the change and broke a stored client secret.