Search code examples
pythonoutlookoffice365chilkatchilkat-email

Unable to access Microsoft mailboxes using OAuth2 with Chilkat2


I am trying to access some mailboxes using the Pop3 protocol through my works proxy. I can get my oauth token, and access my information using Chilkat2 HTTP Library.

Using this code gets me a response of my profile:

http = chilkat2.Http()
http.AuthToken = accesstoken
http.ProxyDomain = "Some Proxy"
http.ProxyPort = Some Port

answer = http.QuickGetStr("https://graph.microsoft.com/v1.0/me")
print(answer)

which retunrs this

{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users/$entity"................ ect

This returns my profile details from the Windows servers so I know my oauth2 token is valid and works.

I then try and use the MailMan protocol to open up my POP3 Mailbox I run in to an authentication error, I run the code below

mailman = chilkat2.MailMan()
mailman.HttpProxyHostname = "Some Proxy"
mailman.HttpProxyPort = Some Port

mailman.MailHost = "outlook.office365.com"
mailman.MailPort = 995
mailman.PopSsl = True
mailman.PopUsername = username
mailman.PopPassword = ""
mailman.OAuth2AccessToken = accesstoken

mailman.Pop3EndSession() #close session as program keeps breaking and leaving session open

success = mailman.Pop3Connect()
if (success != True):
    print(mailman.LastErrorText)
    sys.exit()

# Authenticate..
success = mailman.Pop3Authenticate()
if (success != True):
    print(mailman.LastErrorText)
    sys.exit()

However the authenticate command always returns as false, the Chilkat error log shows as below:

ChilkatLog:
  Pop3Authenticate:
    DllDate: Feb  9 2021
    ChilkatVersion: 9.5.0.86
    UnlockPrefix: Auto unlock for 30-day trial
    Architecture: Little Endian; 64-bit
    Language: Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)], win32
    VerboseLogging: 0
    Pop3Authenticate:
      username: my username
      popSPA: 0
      greeting: +OK The Microsoft Exchange POP3 service is ready. [TABPADIAUAAyADYANQBDAEEAMAAzADgANgAuAEcAQgBSAFAAMgA2ADUALgBQAFIATwBEAC4ATwBVAFQATABPAE8ASwAuAEMATwBNAA==]
      pop_office365_xoauth2:
        PopCmdSent: AUTH XOAUTH2
        PopCmdResp: +
        auth_xoauth2_response_1: +

        PopCmdSent: <base64 string in XOAUTH2 format>
        PopCmdResp: -ERR Authentication failure: unknown user name or bad password.
        POP3 response indicates failure.
        AUTH_XOAUTH2_response: -ERR Authentication failure: unknown user name or bad password.

      --pop_office365_xoauth2
      POP3 authentication failed
    --Pop3Authenticate
    Failed.
  --Pop3Authenticate
--ChilkatLog

I am at a loss, I have used every combination of scope that should allow me this access with my token, but I cannot get it to work with any of the email libraries in Chilkat; seems to connect fine with the servers but always fails the authentication. Anyone got any idea on this?


Solution

  • My guess is that something wasn't setup correctly in Azure, and/or you're not asking for the correct scopes when getting the OAuth2 access token. This example has comments that describe the App Registration in Azure Active Directory: https://www.example-code.com/chilkat2-python/office365_oauth2_access_token.asp At each step, there is a link to the Azure Console screen as I was doing it.

    Also, your scope should look like this:

    oauth2.Scope = "openid profile offline_access https://outlook.office365.com/SMTP.Send https://outlook.office365.com/POP.AccessAsUser.All https://outlook.office365.com/IMAP.AccessAsUser.All"

    There are places in the Microsoft documentation where the scopes are different (or old?). The interactive 3-legged OAuth2 flow only has to be done once. After you have the OAuth2 access token, you can continually refresh without user interaction as shown here: https://www.example-code.com/chilkat2-python/office365_refresh_access_token.asp

    Alternatively, you can try the resource owner grant flow as shown here: https://www.example-code.com/chilkat2-python/office365_resource_owner_password_credentials_grant.asp The resource-owner flow is non-interactive and is for apps accessing its own O365 account.

    Please let me know if that helps.