Search code examples
pythonazureazure-active-directoryoffice365exchangelib

exchangelib OAUTH authentication NonExistentMailbox error


I have a Python script that is reading Office 365 emails and downloading attachments. I am using exchangelib and trying to switch from Basic Authentication to OAUTH2.

My old script was authenticating without any issues:

from exchangelib import Credentials, Account

username = 'xxx@yyy.com'
pwd = '123456'
credentials = Credentials(username, pwd)
account = Account(username,
              credentials=credentials, autodiscover=True)

The new one one:

from exchangelib import OAuth2Credentials

username = 'xxx@yyy.com'
tenant_id = 'TENANT ID'
client_id = 'CLIENT ID'
secret_value = 'CLIENT SECRET'
credentials = OAuth2Credentials(client_id=client_id, client_secret=secret_value, tenant_id=tenant_id)
account = Account(username,
              credentials=credentials, autodiscover=True)

The new script returns an error:

exchangelib.errors.ErrorNonExistentMailbox: The SMTP address has no mailbox associated with it

I have created and registered app in Azure portal. Email/User is added to app.


Solution

  • I tried to reproduce the same in my environment and got the below results:

    I created one Azure AD application and added API permissions with admin consent as below:

    enter image description here

    Now, I ran the same code as you and got the same error as below:

    from exchangelib import OAuth2Credentials
    
    username = 'xxx@tenant.onmicrosoft.com'
    tenant_id = 'TENANT ID'
    client_id = 'CLIENT ID'
    secret_value = 'CLIENT SECRET'
    credentials = OAuth2Credentials(client_id=client_id, client_secret=secret_value, tenant_id=tenant_id)
    account = Account(username, credentials=credentials, autodiscover=True)
    

    Response:

    enter image description here

    To resolve the error, try making few changes in your code like below:

    from exchangelib import OAuth2Credentials
    
    username = 'xxx@tenant.onmicrosoft.com' ## make sure to give valid address
    tenant_id = 'TENANT ID'
    client_id = 'CLIENT ID'
    secret_value = 'CLIENT SECRET'
    version = Version(build=Build(15, 0, 12, 34))
    credentials = OAuth2Credentials(client_id=client_id, client_secret=secret_value, tenant_id=tenant_id)
    
    config = Configuration(service_endpoint = 'https://outlook.office365.com/EWS/Exchange.asmx',
                            credentials=credentials,
                            auth_type=OAUTH2 , 
                            version=version)
    account = Account(username, credentials=credentials, autodiscover=False, config=config, access_type=IMPERSONATION)
    mails = list(account.inbox.filter(is_read=False).only(
            'is_read', 'subject', 'body','text_body','datetime_received',
            'sender','to_recipients','cc_recipients','bcc_recipients',
            'attachments','importance'
        ).order_by('datetime_received')[:1])
    print(mails)
    

    Response:

    enter image description here

    Make sure whether the user has required licenses assigned or not as below:

    Go to Azure Active Directory -> Users -> All users -> Select User -> Licenses

    enter image description here