davmail icon indicating copy to clipboard operation
davmail copied to clipboard

O365Modern erroneous auth failure

Open nitz opened this issue 2 years ago • 7 comments

Hello!

First: Thanks so much for this, it has really helped me out since we are stuck using O365Modern but have a legacy service that doesn't support the auth flow yet! As such, I'm running it headless with non-interactive password access.

I've been using davmail for a while now quite successfully, but started having auth failures this morning. I'd approve the sign-in on my app like usual, but it never seemed to allow me in. Update to v6.0.1, re-did my properties file, still the same.

The errors I was getting were something like this:


2021-12-16 09:40:32,130 ERROR [ImapConnection-53468] davmail  - Authentication failed: invalid user or password
davmail.exception.DavMailAuthenticationException: Authentication failed: invalid user or password
        at davmail.exchange.auth.O365Authenticator.authenticate(O365Authenticator.java:217)
        at davmail.exchange.ExchangeSessionFactory.getInstance(ExchangeSessionFactory.java:182)
        at davmail.exchange.ExchangeSessionFactory.getInstance(ExchangeSessionFactory.java:93)
        at davmail.imap.ImapConnection.run(ImapConnection.java:155)

I thought this just simply couldn't be right, because the password hadn't changed. I went over to the M365 portal and checked login failures for the user, and found this message: Sign-in was interrupted due to a password reset or password registration entry.

After a bit of googling around, I didn't find anything useful there. Eventually I tried to simply login as the user on a desktop. Got the auth push notification and approved it as usual, but rather than being signed in, I got dropped on the "is this information up to date?" page, asking if my phone number, recovery email, and auth app were still current!

I said yes they were, and it allowed me to finish logging in... (I imagine you see where this is going.)

Flipped back to my service and made it re-try the auth, got the push notification, approved it, and boom. Working just like you'd expect.

It seems that the "security info update" flow blocks login completely until it's approved. The "invalid user or password" message was a bit of a red herring, as it turns out that info was completely fine, it was just Microsoft being Microsoft.

I don't know if you have a way to handle that on your end, or if it's something you could emit a more concise error for, but I wanted to post this here in the very least hopes that there's gonna be someone else with the problem and this might help them.

Cheers

nitz avatar Dec 16 '21 14:12 nitz

Thanks for your feedback... would need a way to trigger this on a test account to implement the missing use case in DavMail.

However you used the right approach whenever authentication fails with DavMail: just check browser based authentication once to get rid of any password expired / security info update issue.

Side note, this may help: https://support.rm.com/technicalarticle.asp?cref=tec6276129

mguessan avatar Dec 22 '21 10:12 mguessan

would need a way to trigger this on a test account to implement the missing use case in DavMail.

Seriously! I can't even figure out where exactly in the M365 Admin / AAD Admin that it's set to even require this "update" at any interval. (I'm sure it must be somewhere, but as they are merging all of their stuff into AAD and the sort, it's a bit of a cluster...)

I will let you know if I manage to find a way to reliably trigger or flag the account so it's something that could be tested against!

nitz avatar Dec 22 '21 13:12 nitz

Might be a dup of #182 because I expire the same problem and it contains both errors:

2022-06-21 13:57:39,626 DEBUG [ImapConnection-58040] davmail.exchange.auth.O365Authenticator  - O365 returned error: 
2022-06-21 13:57:39,629 INFO  [ImapConnection-58040] davmail.connection  - FAILED - 127.0.0.1:58040 $mylogin
2022-06-21 13:57:39,630 ERROR [ImapConnection-58040] davmail  - Authentication failed: invalid user or password
davmail.exception.DavMailAuthenticationException: Authentication failed: invalid user or password
	at davmail.exchange.auth.O365Authenticator.authenticate(O365Authenticator.java:208)
	at davmail.exchange.ExchangeSessionFactory.getInstance(ExchangeSessionFactory.java:183)
	at davmail.exchange.ExchangeSessionFactory.getInstance(ExchangeSessionFactory.java:99)
	at davmail.imap.ImapConnection.run(ImapConnection.java:113)

Cybso avatar Jun 21 '22 12:06 Cybso

It seems that response property strServiceExceptionMessage is set but empty

Cybso avatar Jun 21 '22 12:06 Cybso

Found two issues.

First, O365Authenticator#handleMfa() returns null because of policy reasons, but the error message got only visible after I modified O365Authenticator to write processAuthMethod.getResponseBodyAsString() into the logger. The request returned a HTML login form with the error message "An administrator of ... has set a policy that prevents you from granting DavMail the permissions it is requesting.".

Secondly, it seems that config.optString() never returns null but an empty string if the property is not been set in the JSON response. So the line

} else if (config.optString("strServiceExceptionMessage") != null) {

should be changed into

} else if (config.optString("strServiceExceptionMessage") != null && !config.optString("strServiceExceptionMessage").isEmpty()) {

Cybso avatar Jun 21 '22 13:06 Cybso

Besides this, I think the problem is that I missed this line from the FAQ:

"You will have to give your consent to DavMail access on first call, check davmail log for exact url or use O365Interactive once" http://davmail.sourceforge.net/faq.html

Maybe davmail should grep the response and print a reference to the FAQ entry in return?

Cybso avatar Jun 21 '22 13:06 Cybso

@Cybso - I did find an additional workaround that has saved me some of the headaches associated with this.

The thing that kept getting my accounts that used davmail hung up was actually the self-service password reset. Turns out every 180 days (or something along those lines), MS would force the account to do an interactive login to just verify that the recovery methods were valid. (Something I definitely wanted for my normal users, but had no need on the account I was using with davmail, as it was just used by an application.)

From the AAD dashboard, select your tenant, then "Password Reset". With "Properties" selected, I switched the "Self service password reset enabled" option from "All" to "Selected", and then chose a group I have that all my actual staff belongs to. (That way, any of my app specific accounts/ones that aren't tied to real humans aren't able to access the self service password reset.)

That cleared it up for me and the next time DavMail logged in (and I approved the MFA request), everything went peachy.

nitz avatar Jun 21 '22 14:06 nitz