Microsoft OAuth2 SMTP

2024-10-02 04:18:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试构建一个应用程序,用Python从我的Microsoft office电子邮件帐户发送电子邮件,使用SMTP进行发送,使用OAuth2进行身份验证。身份验证不起作用,我得到reply: retcode (535); Msg: b'5.7.3 Authentication unsuccessful [LO2P265CA0061.GBRP265.PROD.OUTLOOK.COM]'

我在azure上创建了一个AAD应用程序,并下载了设置凭据后提供的示例flask应用程序,我知道这就是repo

我已使用此应用程序(从AAD门户下载,其中包含我的密码),并尝试使用来自的信息将给定令牌用于SMTP身份验证

使用我的办公室电子邮件帐户登录可以正常工作,/graphcall也可以正常工作。但是SMTP身份验证不起作用,我收到了来自它的reply: retcode (535); Msg: b'5.7.3 Authentication unsuccessful [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 [<A.GENERAL.IP>]\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 [<A.GENERAL.IP>]\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 [<A.GENERAL.IP>]\r\n'
reply: retcode (250); Msg: b'LO2P265CA0516.outlook.office365.com Hello [<A.GENERAL.IP>]'
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]'

我做过的事情:

  1. 我们已允许此邮箱使用SMTP
  2. 令牌具有允许的SMTP地址
  3. XOAUTH2令牌编码器的输出与网站上的示例匹配

仅供参考,令牌数据如下所示,已删除令牌和用户名

{
    "access_token": "ey<...>aw",
    "client_info": "ey<...>In0",
    "expires_in": 3599,
    "ext_expires_in": 3599,
    "id_token": "ey<...>jQ",
    "id_token_claims": {
        "aud": "8<...>9",
        "exp": 1634319637,
        "iat": 1634315737,
        "iss": "https://login.microsoftonline.com/5<...>1/v2.0",
        "name": "<Name of the user>",
        "nbf": 1634315737,
        "nonce": "c1<...>d0",
        "oid": "cd<...>1b",
        "preferred_username": "user.name@company.com",
        "rh": "0.A<...>As.",
        "sub": "2w<...>ww",
        "tid": "50<...>31",
        "uti": "8W<...>AA",
        "ver": "2.0"
    },
    "refresh_token": "0.A<...>4Y",
    "scope": "openid profile SMTP.Send User.ReadBasic.All email",
    "token_type": "Bearer"
}

Tags: selfcomtoken身份验证send应用程序usernamemsg
1条回答
网友
1楼 · 发布于 2024-10-02 04:18:54
  1. 通过将“启用安全默认设置”切换为“否”,禁用Azure安全默认设置:

    • 以安全管理员、条件访问管理员或全局管理员身份登录Azure门户
    • 浏览至Azure Active Directory->;财产
    • 选择管理安全默认值
    • 将“启用安全默认值”切换设置为“否”
    • 选择保存
  2. 将用户从阻止旧身份验证的条件访问策略中排除:

    • 以安全管理员、条件访问管理员或全局管理员身份登录Azure门户
    • 浏览至Azure Active Directory>;安全性>;有条件接收
    • 在阻止旧身份验证的策略中,排除用户和组下正在使用的邮箱>;排除
    • 选择保存

您应该使用端口25作为SMTP服务器:apicalsolutions com.mail.protection.outlook.com。作为用户使用您域中的任何用户。即使它没有链接邮箱,您也可以使用它进行登录

阅读更多here

相关问题 更多 >

    热门问题