使用Graph API(OAuth2客户端凭据流)发送邮件时遇405/404错误
问题分析与解决方案
核心问题1:Postman请求体格式不符合Graph API规范
你的请求体结构完全错误,导致服务器无法识别请求,返回405 Method Not Allowed。Graph API的sendMail接口要求的请求体格式如下:
正确请求体示例:
{ "message": { "subject": "This is a test mail", "body": { "contentType": "Text", "content": "This is the message body..." }, "toRecipients": [ { "emailAddress": { "address": "recipient@example.com" } } ] }, "saveToSentItems": true }
关键注意点:
- 无
recipient字段,收件人必须放在message.toRecipients数组中 - 邮件内容需嵌套在
message.body内,明确指定contentType(可选Text或HTML) - 禁止指定
from字段:路径/users/{id/UPN}已明确发件人,客户端凭据流中应用将以该用户身份发送邮件,无需重复设置
核心问题2:404 Not Found的可能原因
使用用户ID调用返回404时,大概率是以下两种情况:
- 用户无Exchange Online许可证:仅拥有Exchange邮箱的用户才能通过Graph API发送邮件,你的用户UPN包含
#EXT#,说明是外部用户,可能未分配Exchange许可证,导致无法找到对应邮件资源。 - 用户ID错误:确认从
/users接口获取的ID完全匹配,避免多余空格或字符。
Java代码优化建议
不要手动拼接UserRequestBuilder路径,使用Graph SDK内置方法更可靠:
String userId = "你的用户ID或UPN"; graphClient.users(userId) .sendMail(UserSendMailParameterSet .newBuilder() .withMessage(message) // 确保message对象结构与Postman的message字段一致 .withSaveToSentItems(true) .build()) .buildRequest() .post();
正确构建message对象的示例:
Message message = new Message(); message.subject = "This is a test mail"; ItemBody body = new ItemBody(); body.contentType = BodyType.TEXT; body.content = "This is the message body..."; message.body = body; Recipient recipient = new Recipient(); EmailAddress emailAddress = new EmailAddress(); emailAddress.address = "recipient@example.com"; recipient.emailAddress = emailAddress; message.toRecipients = Arrays.asList(recipient);
额外验证步骤
- 确认目标用户(发件人)已分配Exchange Online许可证:在Azure AD或Microsoft 365 admin center中检查许可证状态。
- 先通过Postman验证正确请求体:确保Postman请求成功后再迁移到Java代码,降低排查复杂度。
- 检查令牌
aud字段:解码令牌确认受众为https://graph.microsoft.com,避免权限范围错误。
内容的提问来源于stack exchange,提问作者bisi
相关产品推荐
相关产品推荐

