Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >微软OAuth2 SMTP

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

我已经在azure上创建了一个AAD应用程序,并下载了在设置凭据之后提供的示例烧瓶应用程序,据我所知,它就是这个存储库

我使用了这个应用程序(从带有我的秘密的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的类,我是基于这些类编写的:

代码语言:javascript
运行
AI代码解释
复制
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以进行正常检查:

代码语言:javascript
运行
AI代码解释
复制
@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"],
    )

身份验证失败了,下面是完整的日志:

代码语言:javascript
运行
AI代码解释
复制
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令牌编码器的输出与网站上示例的输出相匹配

令牌数据如下所示,删除了令牌和用户名

代码语言:javascript
运行
AI代码解释
复制
{
    "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"
}
EN

回答 1

Stack Overflow用户

发布于 2021-10-24 04:01:20

  1. 通过将“启用安全性默认值”切换到“否”,禁用Azure Security默认设置:
代码语言:javascript
运行
AI代码解释
复制
- Sign in to the Azure portal as a security administrator, conditional access administrator, or Global administrator.
- Browse to Azure Active Directory -> Properties.
- Select Manage security defaults.
- Set the Enable security defaults toggle to No.
- Select save.
  1. 将用户排除在阻止遗留身份验证的条件访问策略之外:
代码语言:javascript
运行
AI代码解释
复制
- Sign in to the Azure portal as a Security administrator, Conditional Access administrator, or Global administrator.
- Browse to Azure Active Directory > Security > Conditional Access.
- In the policy that blocks legacy Authentication, exclude the mailbox being used under Users and Groups > Exclude.
- Select Save.

您应该使用SMTP服务器:带有apicalsolutions-com.mail.protection.outlook.com端口25的。当用户使用您域的任何用户时。即使它没有链接邮箱,您也可以用来登录。

阅读更多的这里

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69588201

复制
相关文章
根据获取内部元素的高度,设置iframe的高度
iframe 是一个非常迷得一个元素,很难直接获取其内部元素的高度。 下面分享一个方法,可以获取 iframe 内部元素的高度: function setIframeHeight(id){     try{         var iframe = document.getElementById(id);         if(iframe.attachEvent){             iframe.attachEvent("onload", function(){                 i
德顺
2019/11/13
9.5K0
jquery中获取元素的几种方式小结
1 从集合中通过指定的序号获取元素 <div> <p>0</p> <p>1</p> <p>2</p> <p>3</p> <p>4</p> <p>5</p> <p>6</p> <p>7</p> </div> <script type="text/javascript"> jQuery(function(){ $("p").eq(2).css("color","red"); $("p").eq(3).css("color","red"); }) </script> 2
用户7657330
2020/08/14
2K0
jquery获取元素绑定的事件
一个简单的记录,在调试jquery的事件绑定时会用到。查看某元素是否绑定上了事件。
the5fire
2019/02/28
4.4K0
JavaScript、Jquery获取屏幕的宽度和高度
在日常的项目中经常需要获取屏幕的宽度或者高度,简单记录一下: Javascript方法获取: document.body.clientWidth //网页可见区域宽 document.body.clientHeight //网页可见区域高 document.body.offsetWidth //网页可见区域宽(包括边线的宽) document.body.offsetHeight //网页可见区域高(包括边线的高) document.body.scrollWidth //网页正文全文宽 document.b
德顺
2019/11/13
5.5K0
jquery获取第几个子元素_js获取元素的指定子元素
通过children方法,children(“input:first-child”)
全栈程序员站长
2022/08/03
27.5K0
jquery 获取鼠标和元素的坐标点
2,获取对象元素的位置(offset()方法) var offset = obj.offset(); 获取对象元素的位置,分别是元素的top和left,调用方法是:offset.left和offset.top,可知当前对象的左部和顶部位置。
Yiiven
2022/12/15
2.5K0
jquery获取元素到页面顶部的距离
在前端开发过程中,经常会遇到要求滚动条滚动到某位置时某按钮固定在页面上,否则悬浮于页面上。这时就会用到获取需要固定在页面位置的元素距离页面顶部的距离,通过比较文档滚动条到顶部的距离和页面元素到顶部距离的大小便可确定。
OECOM
2020/07/01
5.4K0
jQuery中不同元素的作用
removeClass() - 从被选元素删除一个或多个类 toggleClass() - 对被选元素进行添加/删除类的切换操作 css() - 设置或返回样式属性
用户7718188
2021/10/07
1.8K0
jquery获取第几个元素的方法总结
使用jquery时经常会遇到,选择器选择一组元素后,需要在这组元素中找到第几个元素。
江一铭
2022/06/17
1.1K0
jquery获取紧邻的上一个元素
本章节分享一段代码实例,它实现了获取紧邻的上一个同级元素的功能。 代码实例如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.pipipi.net/" /> <title>犀牛前端部落</title> <style type="text/css"> #box li { width: 350px; height: 25px; line-height: 25
IT工作者
2021/12/28
1.4K0
jquery 与javascript 获取元素尺寸大小的对比
jquery获取尺寸的方法 width() 方法设置或返回元素的宽度(不包括内边距、边框或外边距)。 height() 方法设置或返回元素的高度(不包括内边距、边框或外边距)。
tianyawhl
2019/04/04
1.9K0
jQuery获取和设置元素属性
之前使用css方法可以给标签设置样式属性,那么设置标签的其它属性可以使用prop方法了。
落雨
2022/03/01
31K0
jQuery获取和设置元素内容
1. html方法的使用 jquery中的html方法可以获取和设置标签的html内容 示例代码: <script> $(function(){ var $div = $("#div1"); // 获取标签的html内容 var result = $div.html(); alert(result); // 设置标签的html内容,之前的内容会清除 $div.html("<span style='c
落雨
2022/03/01
31.2K0
伪元素的作用_获取iframe中的元素
获取网页源代码也获取不了这些动态渲染的数据 所以用简单的,但是有点麻烦的方法 使用selenium执行js,或者直接在浏览器里面执行js
全栈程序员站长
2022/11/04
7.3K0
伪元素的作用_获取iframe中的元素
jquery实现的倒数获取li元素简单介绍
大家eq()的参数为0的时候就是获取第一个元素,为1的时候就是第二个元素,以此类推。
IT工作者
2022/02/22
1.9K0
js、jQuery 获取文档、窗口、元素的各种值
浏览器当前窗口文档body的宽度: document.body.clientWidth;(仅仅是body的width) 浏览器当前窗口文档body的高度: document.body.clientHeight;(仅仅是body的height)
Krry
2018/09/10
14.5K0
jQuery 替换元素中class的方法
实现方法: ① 使用removeClass()删除旧的class ② 使用addClass()添加新的class ③ 使用attr 直接替换原class ④ 使用 toggleClass 有就移除,没有就添加
青梅煮码
2023/01/16
2.5K0
JavaScript与jQuery获取元素的宽、高和位置
今天汇总整理了 JavaScript 和 jQuery 获取元素宽高和位置的方法,比较全面,方便自己和需要并搜到此文章的朋友们查看。
德顺
2019/11/13
3.2K0
ie8和chrome获取上传图片的宽度和高度等尺寸
测试后可用 <html> <head>     <title>测试</title>     <meta charset="utf-8"/>     <link rel="styleshee
汤高
2018/03/28
1.8K0
JQuery如何获取ID含有特殊字符的DOM元素
为业务需要,DOM元素的ID被命名为“c-order.range”,执行JQuery的DOM查询时,提示如下错误
黄啊码
2021/09/26
11K0

相似问题

IE jQuery返回auto而不是元素宽度

37

获取元素的自动高度,而不将高度设置为auto

22

使用jquery获取元素的可视高度,而不是其实际高度

30

jQuery获取高度(像素)

70

获取计算的高度- Javascript -而不是jQuery

21
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档