【问题标题】:Office 365 IMAP authentication via OAuth2 and python MSAL library通过 OAuth2 和 python MSAL 库的 Office 365 IMAP 身份验证
【发布时间】:2022-10-04 23:42:43
【问题描述】:

我正在尝试升级旧版邮件机器人以通过 Oauth2 而不是基本身份验证进行身份验证,因为它是 now deprecated two days from now

该文档指出应用程序可以保留其原始逻辑,同时仅交换身份验证位

应用程序开发人员构建了发送、读取或 否则,使用这些协议处理电子邮件将能够保留 相同的协议,但需要实现安全的现代身份验证 为他们的用户提供体验。此功能建立在 Microsoft Identity 平台 v2.0 并支持访问 Microsoft 365 电子邮件帐户。

注意我已经明确选择了client credentials flow,因为文档说明

这种类型的授权通常用于服务器到服务器的交互 必须在后台运行,无需立即与 用户。

所以我有一个使用MSAL python library 检索访问令牌的python 脚本。现在我正在尝试使用该访问令牌对 IMAP 服务器进行身份验证。有一些现有的线程显示如何连接到谷歌,我想我的情况非常接近this one,除了我连接到 Office 365 IMAP 服务器。这是我的脚本

import imaplib
import msal
import logging

app = msal.ConfidentialClientApplication(
    'client-id',
    authority='https://login.microsoftonline.com/tenant-id',
    client_credential='secret-key'
)

result = app.acquire_token_for_client(scopes=['https://graph.microsoft.com/.default'])

def generate_auth_string(user, token):
  return 'user=%s\1auth=Bearer %s\1\1' % (user, token)

# IMAP time!
mailserver = 'outlook.office365.com'
imapport = 993
M = imaplib.IMAP4_SSL(mailserver,imapport)
M.debug = 4
M.authenticate('XOAUTH2', lambda x: generate_auth_string('user@mydomain.com', result['access_token']))

print(result)

IMAP 身份验证失败,尽管设置了M.debug = 4,但输出不是很有帮助

  22:56.53 > b'DBDH1 AUTHENTICATE XOAUTH2'
  22:56.53 < b'+ '
  22:56.53 write literal size 2048
  22:57.84 < b'DBDH1 NO AUTHENTICATE failed.'
  22:57.84 NO response: b'AUTHENTICATE failed.'
Traceback (most recent call last):
  File "/home/ubuntu/mini-oauth.py", line 21, in <module>
    M.authenticate("XOAUTH2", lambda x: generate_auth_string('user@mydomain.com', result['access_token']))
  File "/usr/lib/python3.10/imaplib.py", line 444, in authenticate
    raise self.error(dat[-1].decode('utf-8', 'replace'))
imaplib.IMAP4.error: AUTHENTICATE failed.

知道我可能出错的地方,或者如何从 IMAP 服务器获取有关身份验证失败原因的更可靠的信息吗?

我看过的东西

import base64

user = 'test@contoso.onmicrosoft.com'
token = 'EwBAAl3BAAUFFpUAo7J3Ve0bjLBWZWCclRC3EoAA'

xoauth = "user=%s\1auth=Bearer %s\1\1" % (user, token)

xoauth = xoauth.encode('ascii')
xoauth = base64.b64encode(xoauth)
xoauth = xoauth.decode('ascii')

xsanity = 'dXNlcj10ZXN0QGNvbnRvc28ub25taWNyb3NvZnQuY29tAWF1dGg9QmVhcmVyIEV3QkFBbDNCQUFVRkZwVUFvN0ozVmUwYmpMQldaV0NjbFJDM0VvQUEBAQ=='

print(xoauth == xsanity) # prints True
  • This thread 似乎建议需要获取多个令牌,一个用于图形,另一个用于 IMAP 连接;那可能是我想念的吗?

【问题讨论】:

  • 我也有同样的问题。关于这个还有另一个问题。同样的错误:“AUTHENTICATE failed”,在尝试使用 IMAP 与您之前获得的令牌进行身份验证之后。如果您找到解决方案,请发布。

标签: python email oauth-2.0 office365 imap


【解决方案1】:

试试这个脚本:

import json
import msal

import requests

client_id = '***'
client_secret = '***'
tenant_id = '***'
authority = f"https://login.microsoftonline.com/{tenant_id}"

app = msal.ConfidentialClientApplication(
    client_id=client_id,
    client_credential=client_secret,
    authority=authority)

scopes = ["https://graph.microsoft.com/.default"]

result = None
result = app.acquire_token_silent(scopes, account=None)

if not result:
    print(
        "No suitable token exists in cache. Let's get a new one from Azure Active Directory.")
    result = app.acquire_token_for_client(scopes=scopes)

# if "access_token" in result:
#     print("Access token is " + result["access_token"])


if "access_token" in result:
    userId = "***"
    endpoint = f'https://graph.microsoft.com/v1.0/users/{userId}/sendMail'
    toUserEmail = "***"
    email_msg = {'Message': {'Subject': "Test Sending Email from Python",
                             'Body': {'ContentType': 'Text', 'Content': "This is a test email."},
                             'ToRecipients': [{'EmailAddress': {'Address': toUserEmail}}]
                             },
                 'SaveToSentItems': 'true'}
    r = requests.post(endpoint,
                      headers={'Authorization': 'Bearer ' + result['access_token']}, json=email_msg)
    if r.ok:
        print('Sent email successfully')
    else:
        print(r.json())
else:
    print(result.get("error"))
    print(result.get("error_description"))
    print(result.get("correlation_id"))

来源:https://kontext.tech/article/795/python-send-email-via-microsoft-graph-api

【讨论】:

  • 感谢您的帖子,但有 2 个问题 - 1. 我需要将所有现有逻辑与 IMAP 库一起使用,我不想重写整个代码,只重写身份验证。 2. 这是对 SMTP 的调用,我的问题是关于 IMAP。
猜你喜欢
  • 2015-06-27
  • 2020-08-19
  • 1970-01-01
  • 1970-01-01
  • 2016-12-07
  • 2023-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多