turning off Basic Authentication in Exchange Online - [b'LOGIN failed.']
buttergolemm opened this issue · comments
As of today, logging into the mailbox is no longer possible. Is it due to this: https://techcommunity.microsoft.com/t5/exchange-team-blog/basic-authentication-and-exchange-online-september-2021-update/ba-p/2772210 ??
Error -> imap_tools.errors.MailboxLoginError: Response status "OK" expected, but "NO" received. Data: [b'LOGIN failed.']
Credentials have never changed.
I have been able to turn off Basic Authentication for IMAP until the end of the year. This gives me a little more time. From 01.01.2023 I can no longer get around this problem.
Hi,
Same here, but we could not turn on Basic Auth. However, XOAUTH is not working either.
Are there any plans to support Microsoft Graph auth and use it to retrieve messages?
*See tags
Hello, I'm trying hard to make the xoauth
method work, since Basic Auth is going to be removed completely starting from 2023.
Has someone been able to make it work? How do we should retrieve the access token instead of a password for an automatic application?
I tried the MSAL library provided by Microsoft. I'm able to retrieve an access token but then it gives:
imaplib.IMAP4.error: AUTHENTICATE failed.
when I try to login.
*Note - no external libs in imap_tools
Yes @ikvk I know that there are not external libs in imap_tools. But in some way I need to get an access token in order to use the Mailbox.xoauth2
method. My question was specifically targetting how to get that token.
By the way, I think the relevant documentation is written here: https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth
I'm still not able to authenticate, I'm sure I'm missing something Outlook/Exchange side.
I managed to make it work properly. The Mailbox.xoauth2
works, the tricky part was to setup Outlook. Read carefully that documentation and you should be ok.
* It seemed to me that this was a new authentication method.
@Eugenio-Liso could you share the code you used to resolve this? I'm stuck on the same issue, trying to set up oauth to access an Exchange mailbox.
Whilst not exactly an issue with imap_tools
itself, I'd suggest a code example for Mailbox.xoauth2
login with Exchange would be a pretty helpful thing to document in the repo, since many users likely use this project to access Exchange mailboxes. Since Microsoft has now dropped support for basic authentication, using oauth is likely a more common use case.
@benjamingorman Hi there, sorry for the late answer.
I have been able to make it work with the following code:
from imap_tools import MailBox
import msal
class CustomBaseException(Exception):
def __init__(self, **kwargs: Any):
super().__init__()
self.kwargs = kwargs
def __repr__(self) -> str:
return f"{self.__class__.__name__}: {repr(self.kwargs)}"
def __str__(self) -> str:
return repr(self)
class AccessTokenNotRetrieved(CustomBaseException):
pass
def init_mailbox_with_xoauth2(client_id: str, client_secret: str, authority: str,
mailbox_server: str, mailbox_username: str, mailbox_source_folder: str) -> MailBox:
"""
Initializes a Mailbox which internally uses XOAUTH2 authentication.
:param client_id: the Client ID associated to the app created in AAD (Azure Active Directory)
:param client_secret: the Client Secret associated to the app created in AAD (Azure Active Directory)
:param authority: A URL that identifies a token authority. It should be of the format
``https://login.microsoftonline.com/your_tenant``
:param mailbox_server: The server to which we should connect when fetching emails
:param mailbox_username: The username to use when connecting to the mailbox. Usually an email address
:param mailbox_source_folder: The folder in which we should read emails
:return: A ready-to-use Mailbox instance
"""
app = msal.ConfidentialClientApplication(
client_id=client_id,
authority=authority,
client_credential=client_secret
# token_cache=... # Default cache is in memory only.
# You can learn how to use SerializableTokenCache from
# https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache
)
scope = ['https://outlook.office365.com/.default']
access_token_dict_key = "access_token"
token = app.acquire_token_silent(scope, account=None)
if not token:
token = app.acquire_token_for_client(scopes=scope)
if access_token_dict_key in token:
access_token = token[access_token_dict_key]
mailbox = MailBox(mailbox_server).xoauth2(
mailbox_username, access_token, initial_folder=mailbox_source_folder
)
return mailbox
else:
raise AccessTokenNotRetrieved(
message="Unable to retrieve access token from AAD.",
error=token.get("error"),
error_description=token.get("error_description"),
correlation_id=token.get("correlation_id") # You may need this when reporting a bug
)
- The first parameters
client_id
,client_secret
andauthority
depends on the application that you have created on Microsoft Azure site. Follow this guide to setup your application: https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth
Follow sections Register your application and Get an access token
When you have to choose the authentication method (sectionGet an access token
), follow the subsectionOAuth2 client credentials grant flow
. Also, do not skip the sectionRegister service principals in Exchange
andGet an access token
!
I know that this guide is a little bit long (and confusionary), but it works if you read that carefully. - The param
mailbox_server
usually isoutlook.office365.com
If everything goes well, you have a Mailbox
instance which you can use as usual.
Hope this helps.
@Eugenio-Liso Thanks so much for your sharing. follow your guide, I think I‘m close to success.
I'm currently getting error imaplib.error: AUTHENTICATE failed.
, this may be because my org did not approve me to use Application permissions, so I have tried to use Delegated permissions but it does have POP and IMAP permissions. (related docs).
Traceback (most recent call last):
File "C:\workspace\vmmj\test_xoauth2.py", line 83, in <module>
ret = init_mailbox_with_xoauth2(
File "C:\workspace\vmmj\test_xoauth2.py", line 59, in init_mailbox_with_xoauth2
mailbox = MailBox(mailbox_server).xoauth2(
File "C:\workspace\vmmj\venv\lib\site-packages\imap_tools\mailbox.py", line 87, in xoauth2
result = self.client.authenticate('XOAUTH2', lambda x: auth_string) # noqa
File "C:\Users\xshen\AppData\Local\Programs\Python\Python39\lib\imaplib.py", line 444, in authenticate
raise self.error(dat[-1].decode('utf-8', 'replace'))
imaplib.error: AUTHENTICATE failed.
(venv)
My org provides me another way to get data, so I don't need to get data through outlook anymore, I just share why I might fail (maybe help).
@shenxianpeng That error, if I remember correctly, indicates that you do not have sufficient permissions. I think you need to give the Tenant Consent to your application (and yes, I have only tried Application Permissions).