Wednesday, July 12, 2023

Send email with exchange email using Azure service principal

Following is a generic method to send email with attachments using Azure service principle with Mail.Send permission.

This approach is more secure than classic SmtpClient.SendEmail method. Service principal approach allows you to authenticate using Azure Active Directory, which provides a more secure way of authenticating than using a username and password.

You need to supply Client ID, Tenant ID and Client Secret as parameters.


public async Task<bool> SendGraphEmailAsync(Email email,string clientId, string tenantId, string clientSecret)
{
	bool result = false;
	var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);

	BlobService blobService = new BlobService();
	SharePointRepository sharePointRepository = new SharePointRepository();

	//method to get email template from blob storage template container
	var emailTemplate = await blobService.ReadFileFromBlob("Email-Template.html", "template");

	//method to get attachment from sharepoint
	var csvAttachment = await sharePointRepository.GetAttachmentFromSharePointAsBiyes(email.CSVName);

	var message = new Message
	{
		Subject = email.Subject,
		Body = new ItemBody
		{
			ContentType = BodyType.Html,
			Content = emailTemplate.ToString()
		},
		From = new Recipient
		{
			EmailAddress = new EmailAddress
			{
				Address = email.From
			}
		},
		CcRecipients = new List<recipient>
		{
			new Recipient
			{
				EmailAddress = new EmailAddress
				{
					Address = email.SingleCC
				}
			}
		},
		ToRecipients = new List<recipient>
		{
			new Recipient
			{
				EmailAddress = new EmailAddress
				{
					Address = email.SingleTo
				}
			}
		},
		Attachments = new List<microsoft .graph.models.attachment="">
		{
			new FileAttachment
			{
				OdataType = "#microsoft.graph.fileAttachment",
				Name = email.CSVName.Split('/').Last(),
				ContentType = "text/csv",
				ContentBytes = csvAttachment,
			}
		},
	};

	Microsoft.Graph.Users.Item.SendMail
	.SendMailPostRequestBody requestbody = new()
	{
		Message = message,
		SaveToSentItems = false
	};
	var scopes = new[] { "https://graph.microsoft.com/.default" };

	var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

	try
	{
	   await graphClient.Users[email.From]
		.SendMail
		.PostAsync(requestbody);
		return result;
	}
	catch (Microsoft.Graph.ServiceException)
	{
		throw;
	}           
}

Hope that helps