IMAP connection with oauth2 have been failing with response NO AUTHENTICATE failed

Hemanth Bethu - Xaana.Ai 1 Reputation point
2022-10-15T05:36:35.677+00:00

I have been trying to connect IMap server in my application through oauth2, i have created an azure application and given all the API permissions including
IMAP.AccessAsUser.All, i'm successfully getting access token, but unable to get authorized for IMAP server. the response is always authentication failed.

    def generate_auth_string(user, token):  
        auth_string = f"user={user}%x01auth=Bearer {token}%x01%x01"  
        # auth_string= base64.b64encode(auth_string.encode('utf-8'))  
        return auth_string  

    client_id = self.client_id  
    client_secret = self.client_secret  
    authority = f"https://login.microsoftonline.com/{tenant_id}"  
    scopes = ['https://outlook.office365.com/.default']  
    app = msal.ConfidentialClientApplication(  
        client_id,  
        client_credential=client_secret,  
        authority=authority)  
    result = app.acquire_token_for_client(scopes=scopes)  

    if "access_token" in result:  
        if self.server_type == 'imap':  
            if self.is_ssl:  
                connection = IMAP4_SSL(self.server, int(self.port))  
            else:  
                connection = IMAP4(self.server, int(self.port))  
            # connection.login(self.user, self.password)  
            connection.debug = 10  

            connection.authenticate("XOAUTH2", lambda x: generate_auth_string(  
                'Hemanth.Bethu@xaana.ai',  
                result['access_token']))  
            connection.select('INBOX')  
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
20,629 questions
{count} votes

5 answers

Sort by: Most helpful
  1. Cédric Counotte 6 Reputation points
    2022-12-20T07:07:17.887+00:00
    1 person found this answer helpful.

  2. Cristian SPIRIDON 4,471 Reputation points
    2022-10-16T11:41:51.373+00:00

    Hi,

    You should ask for the IMAP scope:
    https://outlook.office.com/IMAP.AccessAsUser.All
    in the access token request. The .default scope is for permissions that are already granted to the app.

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

    Hope this helps!

    0 comments No comments

  3. Cédric Counotte 6 Reputation points
    2022-12-08T09:22:58.207+00:00

    I'm having the exact same issue.

    Asking for IMAP scope as suggested simply fails to obtain token with:

    The provided value for scope https://outlook.office.com/IMAP.AccessAsUser.All is not valid. Client credential flows must have a scope value with /.default suffixed to the resource identifier

    Adding .default to that scope, fails again (to obtain token) with:

    The resource principal named https://outlook.office.com/IMAP.AccessAsUser.All was not found in the tenant.

    The issue is during authenticate() call, as if format was incorrect, but I can't find any logs in office admin.


  4. Ishmael Rufus 6 Reputation points
    2022-12-14T23:37:09.423+00:00

    I'm running into a similar issue trying to use IMAP + Oauth as well.

    Time is of the essence as basic auth goes away sometime in January 2023.

    I am having the exact issue too. The only difference is that I'm able to get an Access Token using https://outlook.office.com/IMAP.AccessAsUser.All as my scope parameter.


  5. Ishmael Rufus 6 Reputation points
    2022-12-19T19:22:40.44+00:00

    DO NOT USE Client Credentials flow with IMAP. YOU WILL BE WASTING YOUR TIME.

    This feature was supposed to be supported by December 2021. It's December 2022.

    You'll have to use Authentication Code Flow to manually extract the session ID and the code via Web.

    YOU MUST SET A REDIRECT URL. Pick Web as your application (because Microsoft loves their questionnaires) and then enter your Redirect URI endpoint. If you don't have an endpoint to handle the URL that is passed you can circumvent this by using http://localhost/test (anything after the slash doesn't matter as long as can carry parameters behind it)

    Finally use this example here to create a URL that you will use to sign in on the inbox: https://stackoverflow.com/questions/73370661/php-connect-mailbox-office-365-with-oauth. The page you get after you successfully log in passes a code and session string. If you created a webservice to handle that you should extract that info. Otherwise you'll have to provide it manually somewhere in your process.

    Upon grant you should obtain a token and a refresh token (for continuous re-login)

    The major drawback is that this process is not fully automated. It requires two points of manual work (one point if you handle the URI request) to connect to your mailbox.

    0 comments No comments