Reputation: 674
A while ago I wrote in C# a simple utility method that was called by an application to send emails automatically.
The application used to authenticate in EWS with Basic authentication (username + password) and everything worked fine.
Starting from September 2022 Microsoft started disabling this now deprecated authentication method, so I decided to update this utility method with an OAuth system autentication. The method is the following:
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();
}
The function is called in a very straightforward way:
MailHelper.SendMail("[email protected]", null, null, null, "[email protected]", "Test subject", false, "This is a test body", null);
The problem is that as soon as the Method emailMessage.Send(); is called, a Microsoft.Exchange.WebServices.Data.ServiceRequestException reporting a 403 forbidden error is thrown.
I already registered the app in the Azure Active Directory interface, set a secret and set the following permissions:
The accounts in my tenant are set to allow Exchange services:
I already double checked IDs and account names to be sure it was not a trivial mistake, but I'm not an expert when it comes to EWS, so I'm surely missing something, unfortunately I don't know where.
Thanks id advance.
Upvotes: 3
Views: 3422
Reputation: 22637
The error 403 Forbidden
usually occurs if you don't have required permissions or missed granting admin consent to the added API permissions.
Please note that, the code you mentioned is using "Client credentials flow" that works with only Application permissions but you added all Delegated permissions.
In that case, you will get 403 Forbidden
error even you granted consent to Delegated permissions.
I tried to reproduce the same in my environment via Postman and got the below results:
I created one Azure AD application and added API permissions same as you like below:
Now, I generated an access token using "Client credentials flow" via Postman like below:
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
Response:
When I used the above token to send mail with below query, I got 403 Forbidden
error like this:
POST https://graph.microsoft.com/v1.0/users/userID/sendmail
Response:
To resolve the error, you need to add Application permissions and grant admin consent to them like below:
Now I generated the access token again and used it in running below query to send sample mail:
In your case, add Application permissions by granting admin consent to them and run the code again.
Upvotes: 3