fix(microsoft-shared): drop User.Read from imap_* scopes to keep token audience on Outlook
Production diagnostic logged:
scopes='email IMAP.AccessAsUser.All Mail.ReadWrite.Shared Mail.Send.Shared
openid profile User.Read'
aud='00000003-0000-0000-c000-000000000000'
The aud is Microsoft Graph's well-known app ID. Outlook's IMAP server only
accepts tokens with aud=https://outlook.office.com — Graph-aud tokens get
rejected with NoResponseError 'AUTHENTICATE failed.' even when the granted
scope list looks right.
Cause: a single Microsoft v2.0 OAuth response can only have one audience.
Mixing Graph-resource scopes (User.Read) with Outlook-resource scopes
(https://outlook.office.com/...) in one request makes Microsoft pick a
single audience for the token. With User.Read present, it picks Graph.
Fix: imap_smtp and imap_leadmail now request only:
- OIDC scopes (offline_access, openid, profile, email) — universal, don't
pin audience and still produce an id_token for oauth_user_email
- Outlook-resource scopes (https://outlook.office.com/IMAP.AccessAsUser.All
and SMTP.Send for imap_smtp)
graph_full keeps its Graph scope set unchanged.
User-side caveat: previously-consented Mail.*.Shared scopes from earlier
graph_full testing are still in Niklas's consent cache and Microsoft will
reflect them back in scp on any new OAuth, potentially re-tainting the
audience choice. Niklas needs to revoke the LeadChat app from
https://myaccount.microsoft.com -> Privacy -> Apps and services to fully
clear those before retrying.
This commit is contained in:
@@ -16,12 +16,20 @@ module MicrosoftSharedConcern
|
||||
Mail.Send.Shared
|
||||
Mail.ReadWrite.Shared
|
||||
].freeze,
|
||||
# imap_* transports MUST request only Outlook-resource scopes (URL-prefixed
|
||||
# https://outlook.office.com/...) plus universal OIDC scopes. Adding any
|
||||
# Graph-resource scope (User.Read, Mail.*, etc.) causes Microsoft to issue
|
||||
# a token with audience=Microsoft Graph (00000003-0000-0000-c000-000000000000)
|
||||
# which the Outlook IMAP/SMTP servers reject with 'AUTHENTICATE failed'.
|
||||
# OIDC scopes (openid, profile, email, offline_access) are universal and
|
||||
# don't pin the audience — they ride alongside whatever resource scope is
|
||||
# requested. The id_token they produce gives us oauth_user_email without
|
||||
# needing User.Read.
|
||||
'imap_smtp' => %w[
|
||||
offline_access
|
||||
openid
|
||||
profile
|
||||
email
|
||||
User.Read
|
||||
https://outlook.office.com/IMAP.AccessAsUser.All
|
||||
https://outlook.office.com/SMTP.Send
|
||||
].freeze,
|
||||
@@ -30,7 +38,6 @@ module MicrosoftSharedConcern
|
||||
openid
|
||||
profile
|
||||
email
|
||||
User.Read
|
||||
https://outlook.office.com/IMAP.AccessAsUser.All
|
||||
].freeze
|
||||
}.freeze
|
||||
|
||||
Reference in New Issue
Block a user