Webklex / php-imap

PHP-IMAP is a wrapper for common IMAP communication without the need to have the php-imap module installed / enabled. The protocol is completely integrated and therefore supports IMAP IDLE operation and the "new" oAuth authentication process as well.
https://www.php-imap.com
MIT License
314 stars 147 forks source link

Can't connect to Microsoft Exchange Server oAuth IMAP: NO AUTHENTICATE failed #207

Closed freescout-helpdesk closed 2 years ago

freescout-helpdesk commented 2 years ago

This is similar to https://github.com/Webklex/php-imap/issues/81

We are having troubles authenticating to Microsoft Exchange Server. Scope is https://outlook.office.com/IMAP.AccessAsUser.All

2022-03-01_18-10-45

>> TAG1 AUTHENTICATE XOAUTH2 dXNlcj1...
<< NO AUTHENTICATE failed.

got failure response: NO AUTHENTICATE failed.

>> TAG2 LOGOUT
<< BYE Microsoft Exchange Server IMAP4 server signing off.

<< OK LOGOUT completed.

What can be wrong?

freescout-helpdesk commented 2 years ago

The Microsoft Exchange user has Mail license.

IMAP config:

    'host'          => 'outlook.office365.com',
    'port'          => '993',
    'encryption'    => 'ssl',
    'validate_cert' => true,
    'username'      => 'freescout@freescout.onmicrosoft.com',
    'password'      => 'AccessToken',
    'protocol'      => 'imap',
    'authentication' => 'oauth',

"_openssl sclient -crlf -connect outlook.office365.com:993" shows same error:

NO AUTHENTICATE failed.
TAG2 LOGOUT
BYE Microsoft Exchange Server IMAP4 server signing
OK LOGOUT completed.
HelloSebastian commented 2 years ago

I am not currently using Microsoft Exchange, however perhaps this could help:

According to Microsoft's documentation, the URL must be

https://outlook.office.com/IMAP.AccessAsUser.All

see here

In the authenticate($user, $token) method in ImapProtocol the authorization parameters are formed like this:

$authenticateParams = ['XOAUTH2', base64_encode("user=$user\1auth=Bearer $token\1\1")];

What do the \1 mean? According to the documentation, these are not given, but ^A

base64("user=" + userName + "^Aauth=Bearer " + accessToken + "^A^A")

see here

Webklex commented 2 years ago

Hi @freescout-helpdesk , thanks for this question; please take a look at the documentation https://www.php-imap.com/examples/oauth @EthraZa has provided.

I hope this helps :)

P.s.: I've sent you an email a few month ago and never heard back - the offer still stands :)

Best regards, Webklex

freescout-helpdesk commented 2 years ago

Apparently the problem is with URL we are using to get Access Token. This one https://login.microsoftonline.com/common/oauth2/v2.0/authorize from documentation does not work:

unauthorized_client: The client does not exist or is not enabled for consumer

While https://login.windows.net/common/oauth2/authorize works fine but received Access Token results in NO AUTHENTICATE failed. response from IMAP.

freescout-helpdesk commented 2 years ago

We were using common endpoint and this was the error message:

Application 'redacted' is not configured as a multi-tenant application. Usage of the /common endpoint is not supported for such applications created after '10/15/2018'. Use a tenant-specific endpoint or configure the application to be multi-tenant

Going in the app settings in Azure to "Authentication >> Supported account types" and selecting "Accounts in any organizational directory (Any Azure AD directory - Multitenant)" fixed the issue.

Webklex commented 2 years ago

Hi @freescout-helpdesk , if you don't want to use a multi tenant app, you can use the AD-app id as tenant instead of common.

Best regards,