1

I have a program to generate emails in one mailbox's drafts folder. Recently I enhanced it to use Microsoft's OAUTH2 authentication for IMAP. Followed this suggestion by Sardar Agabejli and it worked as well -

Office 365 IMAP authentication via OAuth2 and python MSAL library

My program generates lots of mails in batches. Now I am observing that after generating some mails my program hangs waiting for the token forever. It hangs at this step -

result = app.acquire_token_for_client(scopes=conf['scope'])

Here is the reference code:

import imaplib
import msal
import pprint

conf = {
    "authority": "https://login.microsoftonline.com/XXXXyourtenantIDXXXXX",
    "client_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX", #AppID
    "scope": ['https://outlook.office365.com/.default'],
    "secret": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", #Key-Value
    "secret-id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", #Key-ID
}
    
def generate_auth_string(user, token):
    return f"user={user}\x01auth=Bearer {token}\x01\x01"    


app = msal.ConfidentialClientApplication(conf['client_id'], authority=conf['authority'],
                                             client_credential=conf['secret'])

result = app.acquire_token_silent(conf['scope'], account=None)

if not result:
    print("No suitable token in cache.  Get new one.")
    result = app.acquire_token_for_client(scopes=conf['scope'])
        
    imap = imaplib.IMAP4('outlook.office365.com')
    imap.starttls()
    imap.authenticate("XOAUTH2", lambda x: generate_auth_string("target_mailbox@example.com", result['access_token']).encode("utf-8"))

Has anyone came across this and found the root cause?

I've read few blogs /forums pointing to firewall issue but answers where not clear and couldn't understand why firewall will allow first few mails and then blocks.

  • Hello [elf](https://stackoverflow.com/users/2404453/elf), I found this answer _[link](https://stackoverflow.com/a/73885262/16705263)_ by you on a similar question where you suggested fixing the proxy/firewall solved this for you. What exactly did you do, can you please elaborate. – Shirish Dubey Mar 03 '23 at 05:43

1 Answers1

0

Using result = app.acquire_token_for_client(scopes=conf['scope']) in the first place instead of result = app.acquire_token_silent(conf['scope'], account=None) is better. access_token provided by acquire_token_for_client remains active for a longer duration, can say that based on my testing.

import imaplib
import msal
import pprint

conf = {
"authority": "https://login.microsoftonline.com/XXXXyourtenantIDXXXXX",
"client_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX", #AppID
"scope": ['https://outlook.office365.com/.default'],
"secret": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", #Key-Value
"secret-id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", #Key-ID
}

def generate_auth_string(user, token):
    return f"user={user}\x01auth=Bearer {token}\x01\x01"    


app = msal.ConfidentialClientApplication(conf['client_id'],
authority=conf['authority'],
client_credential=conf['secret'])

result = app.acquire_token_for_client(scopes=conf['scope'])
    
imap = imaplib.IMAP4('outlook.office365.com')
imap.starttls()
imap.authenticate("XOAUTH2", lambda x: generate_auth_string("target_mailbox@example.com", result['access_token']).encode("utf-8"))