I have the same exact problem. I have OAuth2 working for IMAP and SMTP on Exchange, and IMAP/POP/SMTP on Gmail, but it doesn't work on POP/Exchange. There is definitely something going on.
Office 365 OAuth2 working correctly for IMAP, not working for POP3
Hello, I implemented OAuth2 for authenticating an IMAP and POP connection for Outlook.com accounts in my app, using the authorization code flow, following the steps defined in "https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth"
I implemented this in Node.js a few months ago and it was working correctly. However recently POP3 stopped working, whilst IMAP still works fine. POP3 works correctly when using Basic Authentication (username + password)
These are the steps I follow to see if the process works correctly (outside of my Node.js app). Please correct me if anything is wrong:
1. Create an app
- Go to portal.azure.com/#home
- Manage Azure Active Directory / View
- App registrations / New Registration
- Set the name
- Set the supported account types to:
- "Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)"
- Set the redirect URI to https://(myapp)/callback/
- Create a secret: Certificates and secrets / New Client Secret (Set the name and the expiry time to 24 months)
- Set up permissions: API permissions / Add a permission / Microsoft Graph / Delegated permissions / add "openid", "offline_access", "POP.AccessAsUser.All", "IMAP.AccessAsUser.All". Then I remove the "User.Read" permission set by default.
- I get the Application (client) ID and the client secret that I will use later in my requests
2. Create an account that I will connect to
- Go to outlook.live.com/owa. Sign In / Create New Account / Set the new account details
- Then Settings / POP and IMAP / Set "Let devices and apps use POP" to Yes, and select "Let apps and devices delete messages from Outlook"
3. Request access to emails via IMAP using Postman (this works correctly)
- Create the following url which I paste in a browser
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
client_id=(my_client_id)&
response_type=code&
redirect_uri=(my_redirect_uri)&
response_mode=query&
scope=
openid%20
email%20
offline_access%20
https%3A%2F%2Foutlook.office.com%2FIMAP.AccessAsUser.All
&
state=12345
- This will show a popup which I click Yes, and I get redirected to
(my_redirect_uri)?code=(code)&state=12345
- I use the code to send another request, now to obtain tokens, to https://login.microsoftonline.com/common/oauth2/v2.0/token" with the following key-value pairs in the body
client_id: (my_client_id)
scope: openid email offline_access https://outlook.office.com/IMAP.AccessAsUser.All
redirect_uri: (my_redirect_uri)
grant_type: authorization_code
client_secret (my_client_secret)
code: (code)
- And I get the following:
{
"token_type": "Bearer",
"scope": "https://outlook.office.com/IMAP.AccessAsUser.All",
"expires_in": 3600,
"ext_expires_in": 3600,
"access_token": (access_token),
"refresh_token": (refresh_token),
"id_token": (id_token)
}
- Now with the access token I create the xoauth2 token. One way to create it is in Javascript:
btoa("user=(the_user_that_gave_permission)\x01auth=Bearer (access_token)\x01\x01")
- This creates the xoauth2 token, which I then use to connect via IMAP using openssl:
openssl s_client -showcerts -connect outlook.office365.com:993 -servername outlook.office365.com -crlf
* OK The Microsoft Exchange IMAP4 service is ready.
? AUTHENTICATE XOAUTH2 (xoauth2_token)
? OK AUTHENTICATE completed.
Then I can see the contents of the inbox, e.g.
? SELECT "INBOX"
* 2 EXISTS
* 2 RECENT
4. Request access to emails via POP using Postman (it doesn't work)
- The authorize url now looks like this
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
client_id=(my_client_id)&
response_type=code&
redirect_uri=(my_redirect_uri)&
response_mode=query&
scope=
openid%20
email%20
offline_access%20
https%3A%2F%2Foutlook.office.com%2FPOP.AccessAsUser.All
&
state=12345
- Get the popup again, click Yes, get redirected with a code as before
- Use the code to send another request to https://login.microsoftonline.com/common/oauth2/v2.0/token to obtain tokens for POP, with the following key value pairs in the body:
client_id: (my_client_id)
scope: openid email offline_access https://outlook.office.com/POP.AccessAsUser.All
redirect_uri: (my_redirect_uri)
grant_type: authorization_code
client_secret (my_client_secret)
code: (code)
- I get the following response
{
"token_type": "Bearer",
"scope": "https://outlook.office.com/POP.AccessAsUser.All https://outlook.office.com/IMAP.AccessAsUser.All",
"expires_in": 3600,
"ext_expires_in": 3600,
"access_token": (access_token),
"refresh_token": (refresh_token),
"id_token": (id_token)
}
- Create the xoauth2 token, connect via openssl:
openssl s_client -showcerts -connect outlook.office365.com:995 -servername outlook.office365.com -crlf
+OK The Microsoft Exchange POP3 service is ready. [TABPADIAUAAyADYANQBDAEEAMAAzADcANwAuAEcAQgBSAFAAMgA2ADUALgBQAFIATwBEAC4ATwBVAFQATABPAE8ASwAuAEMATwBNAA==]
AUTH XOAUTH2
+
(xoauth2_token)
-ERR Authentication failure: unknown user name or bad password.
- It fails. I create another email account from scratch, only asking for POP3, in case the fact that I was asking for IMAP and POP is causing a conflict. When I create this new account, allow POP3 connections as mentioned before. Follow all the steps mentioned above, and it fails to connect again.
- Can anyone help me with what is the problem, or what am I missing? this was working correctly a few months ago. Is there a way that I can see the status of the POP3 servers? Or a wait to get information about what is causing this issue?
Thanks in advance.