如何通过 cloudfoundry 应用程序从我的系统帐户(我有名称和密码)发送电子邮件

问题描述 投票:0回答:1

今天我一整天都在用 python 处理 OAuth 和 MSAL 的东西。我有一个简单的应用程序,用户填写我的表单,单击提交,然后我将他们的内容写入数据库。我想向他们发送一封电子邮件,内容是“我已将您的内容写入数据库”,我希望该电子邮件来自我的系统帐户,即 AZAD 帐户。

我觉得我应该能够以某种方式获得一个令牌,仅使用名称、密码即可与图形 API 进行交互,然后发送电子邮件。然而我总是碰壁。

我无法为我的应用程序获取管理员内容,以便以任何用户身份发送电子邮件。我想做的就是从我的系统帐户发送一封电子邮件。我可以在桌面上的 Outlook 应用程序中手动执行此操作,但无法从 python IDE 执行此操作。

如果可能的话,我想使用 HTTP 请求来完成此操作

import requests_oauthlib
from requests_oauthlib import OAuth2Session
from oauthlib.oauth2 import LegacyApplicationClient
tenant_id = tid
client_id = cid
client_secret = cs
uri =f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
username=un
password=pw

#DOES NOT WORK says the user account doesn't exist
oauth = OAuth2Session(client=LegacyApplicationClient(client_id=client_id))
token = oauth.fetch_token(
    token_url=uri
    ,client_id=client_id
    ,client_secret=client_secret
    ,username=username
    ,password=password
    ,scope="Mail.Send"
    )

#THIS DOES WORK BUT I CANT GET IT TO EMAIL
client = BackendApplicationClient(client_id=client_id)
oauth = OAuth2Session(client=client)
token = oauth.fetch_token(
    token_url=uri
    ,client_id=client_id
    ,client_secret=client_secret
    ,scope=["https://graph.microsoft.com/.default"]
    )

recipient='[email protected]'
subject="test_subject"
body="test_body"
request_body = {
    'message': {
        # recipient list
        'toRecipients': [
            {
                'emailAddress': {
                    'address': recipient
                }
            }
        ],
        # email subject
        'subject': subject,
        "body": {
            "contentType": "html",
            "content": body
        },
        'importance': 'normal',

    }
}
headers = {
    'Authorization': 'Bearer ' + token['access_token']
}

GRAPH_ENDPOINT = 'https://graph.microsoft.com/v1.0'
endpoint = GRAPH_ENDPOINT + '/me/sendMail'

response = requests.post(endpoint, headers=headers, json=request_body)
response.raise_for_status()  # Raise an exception if request fails

if response.status_code == 202:
    print(f"Email sent to: {recipient}")
else:
    print(f"Email not sent to: {recipient}")


python oauth azure-active-directory microsoft-graph-api token
1个回答
0
投票

或者,您可以利用

msal
库使用用户名和密码生成访问令牌。

最初,我注册了一个应用程序并授予了

Mail.Send
管理员同意的委派权限,仅允许登录用户发送邮件:

enter image description here

使用用户名密码流程时,请确保启用公共客户端流程选项以避免使用客户端机密:

enter image description here

现在,我运行下面的示例 python 代码来创建带有用户名密码的访问令牌,并得到如下响应

#pip install msal
import msal
import requests

tenant_id = 'tenantId'
client_id = 'appId'
username = '[email protected]'  # System account username (email)
password = 'xxxxxxx'

authority = f"https://login.microsoftonline.com/{tenant_id}"
scope = ["https://graph.microsoft.com/Mail.Send", "https://graph.microsoft.com/User.Read"]

app = msal.PublicClientApplication(client_id, authority=authority)

result = app.acquire_token_by_username_password(
    username=username,
    password=password,
    scopes=scope
)

if "access_token" in result:
    access_token = result['access_token']
    print("Token acquired successfully")

    # Prepare the email
    recipient = '[email protected]'
    subject = "Acknowledgement"
    body = "I wrote your stuff to the database"
    request_body = {
        'message': {
            'toRecipients': [
                {'emailAddress': {'address': recipient}}
            ],
            'subject': subject,
            "body": {"contentType": "html", "content": body},
            'importance': 'normal',
        }
    }

    headers = {
        'Authorization': 'Bearer ' + access_token,
        'Content-Type': 'application/json'
    }

    # Send email on behalf of the user (using '/me/sendMail' since this is a delegated flow)
    GRAPH_ENDPOINT = 'https://graph.microsoft.com/v1.0'
    endpoint = f"{GRAPH_ENDPOINT}/me/sendMail"

    # Send the email
    response = requests.post(endpoint, headers=headers, json=request_body)

    # Check for success
    if response.status_code == 202:
        print(f"Email sent to: {recipient}")
    else:
        print(f"Failed to send email: {response.status_code}, {response.text}")
else:
    print("Failed to acquire token:", result.get("error"), result.get("error_description"))

回复:

enter image description here

为了确认这一点,我在邮件发送成功的用户的

Sent Items
中检查了相同的内容,如下所示:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.