We recently enabled MFA on our account that sends out automated emails to staff/clients, so obviously we need a new way to authenticate that process. OAuth seems like overkill, so I went the "app password" route, which I've done seamlessly through services like Gmail.
But this just isn't working... I get the following error:
smtplib.SMTPAuthenticationError: (535, b'5.7.139 Authentication unsuccessful, the request did not meet the criteria to be authenticated successfully. Contact your administrator. [CH0PR03CA0182.namprd03.prod.outlook.com]')
Note that SMTP Authentication is turned on and I'm using STARTTLS 1.2. I've seen people pass parameters like:
SMTPSecure: 'tls'
SMTPAuth: true;
...but I don't know if that's needed for this, since it was working fine before the MFA switch. I also don't know where/how to send those with smtplib
Does anyone have any advice? I'm told I might need an SMTP Connector? Which also seems like an overcomplication of the process and wasn't mentioned in any MS article that instructed users on setting up app passwords. My code is below, fwiw. I haven't changed ANY of it since turning on MFA:
def send_mail(recipients: str, subject: str, body: str, attachments: list = None, cc: str = None):
credentials = get_credentials()
smtp_srv_name = "smtp.office365.com"
smtp_server = smtplib.SMTP(smtp_srv_name, 587)
msg = MIMEMultipart()
msg['Subject'] = subject
msg['From'] = 'xxxxxxxxxxxxx'
msg['To'] = recipients
msg['Cc'] = cc
msg.attach(MIMEText(body, 'plain'))
if attachments is not None:
for attachment in attachments:
with open(attachment, 'rb') as attachment_fileobject:
part = MIMEBase('application', 'octet-stream')
part.set_payload(attachment_fileobject.read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', f"attachment; filename={Path(attachment).name}")
msg.attach(part)
smtp_server.starttls()
smtp_server.login('xxxxxxxxxxxxx', mc_decrypt(credentials['notices_email_pw'], CRYPT_KEY))
smtp_server.send_message(msg)
smtp_server.close()