Exchange Online 发送邮件(以登录用户的身份)
项目背景
2022年10月4日 微软更改了Exchange的验证方式,原来exchangelib的库没法继续实现邮件的发送。
实现方式
利用Microsoft Graph API 里 发送邮件 - Microsoft Graph v1.0 | Microsoft Learn
POST https://graph.microsoft.com/v1.0/me/sendMail Content-type: text/plain
Authorization: Bearer {token} RnJvbTogQWxleCBXaWxiZXIgPEFsZXhXQGNvbnRvc28uY29tPgpUbzogTWVnYW4gQm93ZW4gPE1l Z2FuQkBjb250b3NvLmNvbT4KU3ViamVjdDogSW50ZXJuYWwgUmVzdW1lIFN1Ym1pc3Npb246IFNh bGVzIEFzc29jaWF0ZQpUaHJlYWQtVG9waWM6IEludGVybmFsIFJlc3VtZSBTdWJtaXNzaW9uOiBT YWxlcyBBc3NvY2lhdGUKVGhyZWFkLUluZGV4OiBjb2RlY29kZWNvZGVoZXJlaGVyZWhlcmUKRGF0 ZTogU3VuLCAyOCBGZWIgMjAyMSAwNzoxNTowMCArMDAwMApNZXNzYWdlLUlEOgoJPE1XSFBSMTMw MU1CMjAwMDAwMDAwRDc2RDlDMjgyMjAwMDA5QUQ5QTlASFdIUFIxMzAxTUIwMDAwLmNvZGVudW0u cHJvZC5vdXRsb29rLmNvbT4KQ29udGVudC1MYW5ndWFnZTogZW4tVVMKWC1NUy1IYXMtQXR0YWNo OgpYLU1TLVRORUYtQ29ycmVsYXRvcjoKWC1NUy1Fe
Access Token的获取
接口中需要用token
1、登录https://portal.azure.com/
2、应用注册
3、创建客户端密码
4、授予API权限
已委托:用户需要登录以自己的身份去操作API
应用程序:用户不需要登录,应用程序可以以任何人的身份操作API,包括收取、发送所有人的邮件等等。
这步需要注意代表搜娱管理员同意后,任何用户不需要单独授权就可以授予访问权限。
如果没有管理权限,有两种方式用户可以给自己授权
1)、Graph 浏览器 - Microsoft Graph
用Graph可视化接口调用里的修改权限进行获取。仅限用浏览器获取的令牌,因为clinet_id好像是浏览器的,然后仅限测试用。
2)、通过拼地址后,通过浏览器给自己的账户授权。
其中scope 中用空格进行分隔,设置需要的权限。
https://login.microsoftonline.com/carsgen.com/oauth2/v2.0/authorize? client_id={client_id} &response_type={response_type} &redirect_uri={redirect_uri} &response_mode=query &scope=offline_access%20user.read%20mail.send &state=12345
5、python 根据msal的库获取access_token
def get_access_token(username="username@abc.com",password="ABCdefg"): client_id = "afaffbc-afaef-faefe-afefe-afeafefef" client_secret = "dafeafaefafewafefffeafa" scope=[] authority_url = 'https://login.microsoftonline.com/abc.com' app = msal.ConfidentialClientApplication(client_id, authority=authority_url,client_credential=client_secret) result=app.acquire_token_by_username_password(username=username,password=password,scopes=scope) print(result) if 'access_token' in result: access_token = result['access_token'] return access_token else: print(result.get("error")) print(result.get("error_description")) token=get_access_token()
6、Python 发送邮件
headers={"Authorization":f"Bearer {token}","Content-type":"application/json"} sendMail = { "message": { "subject": "Meet for lunchtset3?", "body": { "contentType": "Text", "content": "The new cafeteria is open." }, "toRecipients": [ { "emailAddress": { "address": "yifanyang@abc.com" } } ], "ccRecipients": [ { "emailAddress": { "address": "shuoyang@bac.com" } } ] }, "saveToSentItems": "false" } res=requests.post(url="https://graph.microsoft.com/v1.0/me/sendMail",data=json.dumps(sendMail),headers=headers)