Microsoft OAuth2 SMTPPython

Программы на Python
Ответить
Anonymous
 Microsoft OAuth2 SMTP

Сообщение Anonymous »

Я пытаюсь создать приложение, которое отправляет электронные письма из моей учетной записи электронной почты Microsoft Office на Python, используя SMTP для отправки с OAuth2 для аутентификации. Аутентификация не работает, получаю ответ: реткод (535); Сообщение: b'5.7.3 Аутентификация не удалась [LO2P265CA0061.GBRP265.PROD.OUTLOOK.COM]'
Я создал приложение AAD в Azure и загрузил пример приложения flask, которое предлагается там после настройки учетных данных, которое, как я понимаю, представляет собой всего лишь этот репозиторий.
Я использовал это приложение (загруженное с портала AAD с помощью мой секрет в этом) и попытался использовать данный токен для аутентификации SMTP, используя информацию из
  • Microsoft docs 1
  • Microsoft docs 2
Вход в систему с моей учетной записью электронной почты в офисе работает, и /graphcall тоже работает. Однако аутентификация SMTP не работает, я получаю ответ: реткод (535); Сообщение: b'5.7.3 Аутентификация не удалась [LO2P265CA0061.GBRP265.PROD.OUTLOOK.COM]' из него.
Область запрашиваемого токена равна SCOPE = ["User.ReadBasic.All", "https://outlook.office.com/SMTP.Send"] и приложение имеет SMTP.send включен в файле конфигурации.
Вот класс, расширяющий smtplib.SMTP, который я написал на его основе:

import smtplib
import base64

class MicrosoftSMTP(smtplib.SMTP):
def __init__(self, host="smtp.office365.com", port=587, **kwargs):
super().__init__(host=host, port=port, **kwargs)

@staticmethod
def encode_auth_token(username, token):
just_a_str = f"user={username}\x01auth=Bearer {token}\x01\x01"
xoauth2_token = base64.b64encode(just_a_str.encode())

return xoauth2_token

def authenticate(self, username, token):
self.helo()

# first step, we
code, msg = self.docmd("auth", "XOAUTH2")
if code != 334:
raise Exception(msg.decode())

# send the token
self.send(self.encode_auth_token(username, token))


и код для подключения к учетным данным из приложения здесь и добавление страницы, на которой я показываю JSON-токен для проверки работоспособности:

@app.route("/send_to_self")
def send_to_self():
token = _get_token_from_cache(app_config.SCOPE)
if not token:
return redirect(url_for("login"))

# connect to the server
connection = MicrosoftSMTP()
connection.set_debuglevel(True) # for output
connection.starttls()
connection.authenticate(
# same as session["user"]["preferred_username"]
token["id_token_claims"]["preferred_username"],
token["access_token"],
)

# ... would write an email here with connection.sendmail( ... )

connection.quit()

return render_template(
"send_to_self.html",
data=token,
data_session=session["flow"],
data_user=session["user"],
)

Аутентификация не удалась, вот полный журнал:
send: 'ehlo 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa\r\n'
reply: b'250-LO2P265CA0516.outlook.office365.com Hello []\r\n'
reply: b'250-SIZE 157286400\r\n'
reply: b'250-PIPELINING\r\n'
reply: b'250-DSN\r\n'
reply: b'250-ENHANCEDSTATUSCODES\r\n'
reply: b'250-STARTTLS\r\n'
reply: b'250-8BITMIME\r\n'
reply: b'250-BINARYMIME\r\n'
reply: b'250-CHUNKING\r\n'
reply: b'250 SMTPUTF8\r\n'
reply: retcode (250); Msg: b'LO2P265CA0516.outlook.office365.com Hello []\nSIZE 157286400\nPIPELINING\nDSN\nENHANCEDSTATUSCODES\nSTARTTLS\n8BITMIME\nBINARYMIME\nCHUNKING\nSMTPUTF8'
send: 'STARTTLS\r\n'
reply: b'220 2.0.0 SMTP server ready\r\n'
reply: retcode (220); Msg: b'2.0.0 SMTP server ready'
send: 'helo 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa\r\n'
reply: b'250 LO2P265CA0516.outlook.office365.com Hello []\r\n'
reply: retcode (250); Msg: b'LO2P265CA0516.outlook.office365.com Hello []'
send: 'auth XOAUTH2\r\n'
reply: b'334 \r\n'
reply: retcode (334); Msg: b''
send: b'dX......EB'
send: 'quit\r\n'
reply: b'535 5.7.3 Authentication unsuccessful [LO2P265CA0516.GBRP265.PROD.OUTLOOK.COM]\r\n'
reply: retcode (535); Msg: b'5.7.3 Authentication unsuccessful [LO2P265CA0516.GBRP265.PROD.OUTLOOK.COM]'

вещи, которые я заметил:
  • у нас разрешен SMTP для этого почтового ящика
  • токен имеет разрешенный SMTP
  • выходные данные кодировщика токена XOAUTH2 соответствуют примеру на веб-сайте
К вашему сведению, данные токена выглядят так, с токенами и имя пользователя удалено
{
"access_token": "eyaw",
"client_info": "eyIn0",
"expires_in": 3599,
"ext_expires_in": 3599,
"id_token": "eyjQ",
"id_token_claims": {
"aud": "89",
"exp": 1634319637,
"iat": 1634315737,
"iss": "https://login.microsoftonline.com/51/v2.0",
"name": "",
"nbf": 1634315737,
"nonce": "c1d0",
"oid": "cd1b",
"preferred_username": "user.name@company.com",
"rh": "0.AAs.",
"sub": "2www",
"tid": "5031",
"uti": "8WAA",
"ver": "2.0"
},
"refresh_token": "0.A4Y",
"scope": "openid profile SMTP.Send User.ReadBasic.All email",
"token_type": "Bearer"
}


Подробнее здесь: https://stackoverflow.com/questions/695 ... auth2-smtp
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»