不久前,我用 C# 编写了一个简单的实用方法,由应用程序调用来自动发送电子邮件。
该应用程序用于通过基本身份验证(用户名+密码)在 EWS 中进行身份验证,一切正常。
从 2022 年 9 月开始,Microsoft 开始禁用这种现已弃用的身份验证方法,因此我决定使用 OAuth 系统身份验证更新此实用程序方法。 方法如下:
public static void SendMail(string to, string cc, string bcc, string replyTo, string from, string subject, bool isHtmlFormat, string body, string[] attachments)
{
var cca = ConfidentialClientApplicationBuilder.Create("my-app-id")//app id
.WithClientSecret("my-client-secret") //Client secret
.WithTenantId("my-tenant-id") //Id tenant
.Build();
var authResult = cca.AcquireTokenForClient(new string[] { "https://outlook.office365.com/.default" }).ExecuteAsync().Result;
string[] recipients = to.Replace(" ", "").Split(';');
string[] repliesTo = string.IsNullOrWhiteSpace(replyTo) ? Array.Empty<string>() : replyTo.Replace(" ", "").Split(';');
string[] ccs = string.IsNullOrWhiteSpace(cc) ? Array.Empty<string>() : cc.Replace(" ", "").Split(';');
string[] bccs = string.IsNullOrWhiteSpace(bcc) ? Array.Empty<string>() : bcc.Replace(" ", "").Split(';');
ExchangeService service = new ExchangeService
{
Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx"),
Credentials = new OAuthCredentials(authResult.AccessToken),
ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, from)
};
service.HttpHeaders.Add("X-AnchorMailbox", from); //Include x-anchormailbox header
EmailMessage emailMessage = new EmailMessage(service)
{
From = new EmailAddress(from),
Subject = subject,
Body = new MessageBody(isHtmlFormat ? BodyType.HTML : BodyType.Text, body)
};
emailMessage.ToRecipients.AddRange(recipients);
emailMessage.ReplyTo.AddRange(repliesTo);
emailMessage.CcRecipients.AddRange(ccs);
emailMessage.BccRecipients.AddRange(bccs);
foreach (string attachment in attachments ?? Array.Empty<string>())
{
emailMessage.Attachments.AddFileAttachment(attachment);
}
emailMessage.Send();
}
该函数的调用方式非常简单:
MailHelper.SendMail("<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8cc1f5c9e1ede5e0cce1f5cfe3e1fcede2f5a2efe3e1" rel="noreferrer noopener nofollow">[email protected]</a>", null, null, null, "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fab495a89f8a9683ba9783b995978a9b9483d4999597" rel="noreferrer noopener nofollow">[email protected]</a>", "Test subject", false, "This is a test body", null);
问题在于,只要 Method emailMessage.Send();调用时,会抛出 Microsoft.Exchange.WebServices.Data.ServiceRequestException 报告 403 禁止错误。
我已经在 Azure Active Directory 界面中注册了该应用程序,设置了密码并设置了以下权限:
我已经仔细检查了 ID 和帐户名称,以确保这不是一个小错误,但我不是 EWS 方面的专家,所以我肯定遗漏了一些东西,不幸的是我不知道在哪里。
感谢您的提前。
最佳答案
如果您没有所需的权限或错过了对添加的 API 权限授予管理员同意,通常会出现 403 Forbidden
错误。
请注意,您提到的代码使用的是“客户端凭据流”,仅适用于应用程序权限,但您添加了所有<强>委派权限。
在这种情况下,即使您同意委派权限,您也会收到 403 Forbidden
错误。
我尝试通过 Postman 在我的环境中重现相同的结果,并得到以下结果:
我创建了一个 Azure AD 应用程序并添加了 API 权限,如下所示:
现在,我通过Postman使用“客户端凭据流”生成了访问 token ,如下所示:
POST https://login.microsoftonline.com/tenantID/oauth2/v2.0/token
client_id:appID
grant_type:client_credentials
client_secret:secret
scope:https://graph.microsoft.com/.default
回应:
当我使用上述 token 通过以下查询发送邮件时,我收到如下 403 Forbidden
错误:
POST https://graph.microsoft.com/v1.0/users/userID/sendmail
回应:
要解决错误,您需要添加应用程序权限并授予管理员同意 给他们如下:
现在我再次生成访问 token ,并在运行下面的查询中使用它来发送示例邮件:
根据您的情况,通过授予管理员同意来添加应用程序权限,然后再次运行代码。
关于c# - 发送邮件时出现 EWS 和 OAuth 403 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74125340/