简体   繁体   中英

Cannot authenticate to IMAP on office365 using JavaMail

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

1个

we followed all instructions stated at

https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth

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

My two cents on this, if you are still facing authentication failure from javamail trying to connect to mailbox and read emails, First and foremost make sure the application setup in azure active directory has below permissions.

IMAP.AccessAsApp

Mail.Read

Mail.Send (For Sending)

Secondly, Create service principal with the enterprise application id as mentioned in the original post. Once done check here if your generated token has all the roles you have assigned.

Even if you assigned necessary roles and you can able to connect to mailbox via powershell still you might get AUTHENTICATE failed from javamail because you might be using this property (mail.imap.auth.mechanisms) wrongly, replace mail.imap with mail.imaps and it should solve the problem.

"mail.imaps.auth.mechanisms"="XOAUTH2"
"mail.imap.host"="outlookoffice365.com"
"mail.smtp.port"=993
"mail.store.protocol"="imaps"

session.getStore("imaps")
store.connect(host,port,user,token)

Good luck !!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM