We are trying to connect a javamail (1.6) client to our office365 mailbox hosted on office365 using OAUTH2 authentication.
No matter what we do, we keep getting A1 NO AUTHENTICATE failed.
We have registered our application with
API Permission
we followed all instructions stated at
including running the powershell commands to create the principal using the app id and object id, and we granted the app full access to emailbox we want to access.
For authentication we do an HTTP POST as following which generates an access token
This is a client credentials flow with shared secret as explained here https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
https://login.microsoftonline.com/{our tenant id}/oauth2/v2.0/token with
client_id=...
client_secret=...
grant_type=client_credentials
scope=https://outlook.office365.com/.default
our javamail configuration
mail.store.protocol="imap"
mail.imap.host="outlook.office365.com"
mail.imap.port="993"
mail.imap.ssl.enable="true"
mail.imap.starttls.enable="true"
mail.imap.auth="true"
mail.imap.auth.mechanisms="XOAUTH2"
mail.imap.user="<email box>"
then in our java code we connect the store with the access token obtained from the above HTTP POST
store.connect(host, user, oauth2_access_token);
We also tried this powershell script, which returns the same error
https://github.com/DanijelkMSFT/ThisandThat/blob/main/Get-IMAPAccessToken.ps1
I do not believe that problem is specific to JavaMail.
It is extremely difficult to determine if an access token has the correct rights or there is something else that prevents the authentication
What else can we try?
Update 1
If we use the powershell script
https://github.com/DanijelkMSFT/ThisandThat/blob/main/Get-IMAPAccessToken.ps1
passing only the client id and the redirectUri the script prompts me for approval and it succeeds
but if we use clientsecret authorization fails
Update 2
I can successfully use javamail with the access token generated by the powershell script.
Clearly the token created with the clientsecret does not have enough rights to access IMAP or the mailbox
I start to wonder if token requests using client secret do not work because our Azure Active Directory has "security defaults" enabled.
May be MFA is enforced therefore any non-interactive requests are blocked
Update 3
https://jwt.ms allows to decode access tokens
The token created with just the clientid (code grant flow) is very different from the one created with the client_secret (client credentials flow).
In token from "code grant interactive" there is an attribute called "scp" Set of Scopes, which lists scopes regardless of what I have in my client app API permission ????
"scp": "IMAP.AccessAsUser.All Mail.Read Mail.Read.All Mail.Read.Shared Mail.ReadBasic User.Read"
The second token from the client credentials flow, has an attribute "roles", but does not have scopes
"roles": ["IMAP.AccessAsApp"]
RESOLVED!
looking at the access token we noticed that the client credentials flow subject (sub) was an id that we did not setup.
Here is the catch: when creating the service principal using powershell in exchange online, for serviceid you have to use the objectid of the enterprise application.
New-ServicePrincipal -AppId {clientid} -ServiceId {enterprise application objectid} -Organization {tenantid}
When creating an app registration Azure AD, you also create an enterprise application
The application object id is different from enterprise application object id.
The client credentials flow uses the enterprise application object id as the user asking for authorization.
The same for granting access to the mailbox using powershell
Add-MailboxPermission -Identity {email} -User -ServiceId {enterprise application objectid} -AccessRights FullAccess
it is unfortunate that the authentication process is so cumbersome