The problem was the OAuth sign-in URL. We were using:
https://login.microsoft.com/{MICROSOFT_TENANT_ID}/oauth2/v2.0/
…where MICROSOFT_TENANT_ID
is our actual tenant ID.
The solution was to use:
https://login.microsoft.com/commong/oauth2/v2.0/
We were able to figure this out by having someone else log in with their corporate Microsoft account, which displayed a detailed error message:
AADSTS50020: User account 'mailto:******@yyyy.com' from identity provider 'https://sts.windows.net/xxxxxxxx-bdae-4a06-a5a7-xxxxx/' does not exist in tenant 'Default Directory' and cannot access the application 'd9e27c47-838c-4608-8121-d177d0d9d15e'(Terraso) in that tenant. The account needs to be added as an external user in the tenant first. Sign out and sign in again with a different Azure Active Directory user account.
We then Googled AADSTS50020 and found "Error AADSTS50020 - User account from identity provider does not exist in tenant." The section Cause 2 detailed our problem. I reviewed the Python sample code and made adjustments.
We are now able to successfully sign in with both our corporate email addresses and @hotmail.com addresses.
The outside user now gets a different error:
AADSTS165000: Invalid Request: The request tokens do not match the user context. Do not copy the user context values (cookies; form fields; headers) between different requests or user sessions; always maintain the ALL of the supplied values across a complete single user flow. Failure Reasons:[Token values do not match;]
Turns out the OAuth URL still isn't right. Ask noted in "Why does Azure Active Directory OAuth work for me and no one else?" on StackOverflow:
The authorization endpoint is wrong. It should be https://login.microsoftonline.com/... instead of https://login.microsoft.com/....
So we switched it to https://login.microsoft.com/commong/oauth2/v2.0/
and everything works.