Microsoft Graph API 使用企业应用程序的访问令牌发送电子邮件

Yas*_*ash 0 python microsoft-graph-api

我正在编写 python 代码,以使用 Microsoft Graph API 从 Outlook 发送电子邮件。为此,我在 Azure Active Directory 租户中创建了一个企业应用程序。我已向租户授予管理员对 Mail.Send 权限申请的同意。我可以借助此应用程序获取 Graph API 的访问令牌,但无法发送邮件。任何人都可以帮助我理解我的代码有什么问题吗?

Python代码:

from requests import post


CLIENT_SECRET_VALUE = 'CLIENT_SECRET_VALUE'
TENANT_ID = 'TENANT_ID'
CLIENT_ID = 'CLIENT_ID'

LOGIN_URI = f'https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token'

headers = {
    'Host': 'login.microsoftonline.com',
    'Content-Type': 'application/x-www-form-urlencoded'
}


body = {
    'client_id': CLIENT_ID,
    'scope': 'https://graph.microsoft.com/.default',
    'client_secret': CLIENT_SECRET_VALUE,
    'grant_type': 'client_credentials',
    'tenant': TENANT_ID
}


response = post(url=LOGIN_URI, headers=headers, data=body)
response.raise_for_status()
response_body = response.json()

authorization_token = f"{response_body['token_type']} {response_body['access_token']}"

print(authorization_token)

email_header = {
    'Authorization': authorization_token,
    'Content-Type': 'application/json'
}

message = {
    'body': {
        'content': 'Outlook Mail Testing Demo',
        'contentType': 'Text'
    },
    'sender': {
        'emailAddress': {
            'address': 'email.address.of.shared.mailbox@active-directory-tenant.tld',
            'name': 'Name of Shared Mailbox'
        }
    },
    'subject': 'Testing email',
    'toRecipients': [
        {
            'emailAddress': {
                'address': 'temprorary.email.address@another-domain.tld',
                'name': 'Name of person to whom email belongs'
            }
        }
    ]
}

email_body = {
    'message': message
}


email_send_response = post(url='https://graph.microsoft.com/v1.0/users/me/sendMail', headers=email_header, data=email_body)
email_send_response.raise_for_status()
Run Code Online (Sandbox Code Playgroud)

[注意:CLIENT_SECRET_VALUE 由企业应用程序生成。TENANT_ID 和 CLIENT_ID 是分配给应用程序的租户和客户端 ID]

运行代码时,我收到错误:

400 Client Error: Bad Request for url: https://graph.microsoft.com/v1.0/users/me/sendMail
Run Code Online (Sandbox Code Playgroud)

Shi*_*rma 5

您的代码中有两个问题。正如我在评论中指定的第一个问题,当您使用客户端凭据流时,URL 应如下所示。

https://graph.microsoft.com/v1.0/users/{userid/UPN}/sendMail
Run Code Online (Sandbox Code Playgroud)

经过对 python 的长期研究,我发现的第二个问题是,您通过 API 调用感知的正文不是 json 格式。所以我使用了import json方法json.dumps并进行了测试。然后就成功了。

代码:

from requests import post
import json

CLIENT_SECRET_VALUE = 'aX27Q~insds3EvI4z8otRNGHRcCgdjeFOTSpCLPZ'
TENANT_ID = '363147dc-b3be-41a7-af56-f67894ef5a7'
CLIENT_ID = 'e61195e5-7955-4558-9126-37f6cf372d45'

LOGIN_URI = f'https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token'

headers = {
    'Host': 'login.microsoftonline.com',
    'Content-Type': 'application/x-www-form-urlencoded'
}


body = {
    'client_id': CLIENT_ID,
    'scope': 'https://graph.microsoft.com/.default',
    'client_secret': CLIENT_SECRET_VALUE,
    'grant_type': 'client_credentials',
    'tenant': TENANT_ID
}


response = post(url=LOGIN_URI, headers=headers, data=body)
response.raise_for_status()
response_body = response.json()

authorization_token = f"{response_body['token_type']} {response_body['access_token']}"

print(authorization_token)

email_header = {
    'Authorization': authorization_token,
    'Content-Type': 'application/json'
}

message = {
    'body': {
        'content': 'Outlook Mail Testing Demo',
        'contentType': 'Text'
    },
    'sender': {
        'emailAddress': {
            'address': 'email.address.of.shared.mailbox@active-directory-tenant.tld',
            'name': 'Name of Shared Mailbox'
        }
    },
    'subject': 'Testing email',
    'toRecipients': [
        {
            'emailAddress': {
                'address': 'temprorary.email.address@another-domain.tld',
                'name': 'Name of person to whom email belongs'
            }
        }
    ]
}

email_body = {
    'message': message
}

email_send_response = post(url='https://graph.microsoft.com/v1.0/users/1ab4e76f-5f52-44b8-8a72-7d03c05e6ff4/sendMail', headers=email_header, data=json.dumps(email_body))
print(email_send_response)
Run Code Online (Sandbox Code Playgroud)

输出: 在此输入图像描述