如何仅用微软用户名密码获取令牌,通过Office365库调用Graph API发Outlook邮件
仅用用户名密码获取GraphClient令牌的方法
可行方案:使用ROPC认证流
你可以通过资源所有者密码凭据(ROPC)流结合微软公共客户端ID实现仅用用户名密码的认证,无需自行在Azure AD注册应用。
具体实现代码
import msal from office365.graph_client import GraphClient def acquire_token(username, password): # 使用微软官方内置的公共客户端ID(无需自行注册应用) client_id = "d3590ed6-52b3-4102-aeff-aad2292ab01c" authority_url = "https://login.microsoftonline.com/common" # 初始化公共客户端应用实例 app = msal.PublicClientApplication( client_id=client_id, authority=authority_url ) # 通过ROPC流获取令牌,指定邮件发送所需的权限范围 scopes = ["https://graph.microsoft.com/Mail.Send"] token = app.acquire_token_by_username_password( username=username, password=password, scopes=scopes ) if "error" in token: raise Exception(f"令牌获取失败: {token['error_description']}") return token # 替换为你的微软工作/学校账户信息 USERNAME = "your_work_account@company.com" PASSWORD = "your_account_password" # 创建GraphClient实例 client = GraphClient(lambda: acquire_token(USERNAME, PASSWORD)) # 发送测试邮件 client.me.send_mail( subject="ROPC流测试邮件", body="这是通过仅用户名密码认证发送的Outlook邮件", to_recipients=["target_user@example.com"] ).execute_query()
关键注意事项
- 账户类型限制:ROPC流仅支持Azure AD工作/学校账户,不支持个人微软账户(如@outlook.com/@hotmail.com)。
- MFA限制:如果你的账户启用了多因素认证(MFA),该方法会直接认证失败。
- 租户配置限制:部分企业租户可能禁用了ROPC流,需确认租户的Azure AD设置允许该认证方式。
替代方案(适用于MFA或ROPC禁用场景)
如果ROPC流不可用,可以使用设备码认证流,仅需用户在浏览器中输入验证码完成认证,同样无需注册自定义应用:
import msal from office365.graph_client import GraphClient def acquire_token(): client_id = "d3590ed6-52b3-4102-aeff-aad2292ab01c" authority_url = "https://login.microsoftonline.com/common" app = msal.PublicClientApplication( client_id=client_id, authority=authority_url ) scopes = ["https://graph.microsoft.com/Mail.Send"] flow = app.initiate_device_flow(scopes=scopes) if "user_code" not in flow: raise Exception(f"设备码流初始化失败: {flow.get('error_description')}") print(f"请打开链接: {flow['verification_uri']},输入验证码: {flow['user_code']}") token = app.acquire_token_by_device_flow(flow) if "error" in token: raise Exception(f"令牌获取失败: {token['error_description']}") return token client = GraphClient(acquire_token) client.me.send_mail( subject="设备码流测试邮件", body="这是通过设备码认证发送的Outlook邮件", to_recipients=["target_user@example.com"] ).execute_query()
内容的提问来源于stack exchange,提问作者Merlin Nestler
相关产品推荐
相关产品推荐

