genius26
genius26

Reputation: 122

Using Oauth2 to send email via Office365 C#

I'm trying to send email in c# using Oauth2 with an office 365 account.

Currently I am able to get the token but not sure how I'm able to use that token and send the email.

System.Net.Mail does not support OAuth or OAuth2.

I've seen Mailkit but the samples are all for google mail and didn't see one for office 365 so I'm not really sure where to start.

Upvotes: 7

Views: 38559

Answers (3)

adumred
adumred

Reputation: 164

Setup app using this.

   namespace SendEmailWithMicrosoftGraph
    {
        class Program
        {
            static async Task Main(string[] args)
            {
                // Set up the Microsoft Graph API endpoint and version
                string graphApiEndpoint = "https://graph.microsoft.com/v1.0";
    
                // Set up the client application ID and secret
                string clientId = "<clientId>";
                string clientSecret = "<clientSecret>";
                string tenantId = "<tenentId>";
    
                // Set up the user's email address and message content
                string userEmail = "<userEmail>";
                string messageSubject = "Test email";
                string messageBody = "This is a test email sent via Microsoft Graph";
    
                // Set up the authentication context and acquire a token
                var authBuilder = ConfidentialClientApplicationBuilder.Create(clientId)
                    .WithAuthority($"https://login.microsoftonline.com/{tenantId}/v2.0")
                    .WithClientSecret(clientSecret)
                    .Build();
    
                var authResult = await authBuilder.AcquireTokenForClient(new[] { "https://graph.microsoft.com/.default" })
                    .ExecuteAsync();
    
                // Set up the HTTP client and add the access token to the authorization header
                var httpClient = new HttpClient();
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
    
                // Set up the email message
                var emailMessage = new
                {
                    message = new
                    {
                        subject = messageSubject,
                        body = new
                        {
                            contentType = "Text",
                            content = messageBody
                        },
                        toRecipients = new[]
                        {
                            new
                            {
                                emailAddress = new
                                {
                                    address = userEmail
                                }
                            }
                        }
                    }
                };
    
                // Convert the email message to a JSON string and send the email via Microsoft Graph
                var jsonMessage = JsonConvert.SerializeObject(emailMessage);
                var response = await httpClient.PostAsync($"{graphApiEndpoint}/users/{userEmail}/sendMail", new StringContent(jsonMessage, System.Text.Encoding.UTF8, "application/json"));
    
                if (response.IsSuccessStatusCode)
                {
                    Console.WriteLine("Email sent successfully.");
                }
                else
                {
                    Console.WriteLine("Failed to send email. Status code: " + response.StatusCode);
                }
            }
        }
    }

Upvotes: 4

jstedfast
jstedfast

Reputation: 38528

The documentation for OAuth2 authentication using MailKit with Office365 can be found here: https://github.com/jstedfast/MailKit/blob/master/ExchangeOAuth2.md

var options = new PublicClientApplicationOptions {
    ClientId = "Application (client) ID",
    TenantId = "Directory (tenant) ID",
    RedirectUri = "https://login.microsoftonline.com/common/oauth2/nativeclient"
};
 
var publicClientApplication = PublicClientApplicationBuilder
    .CreateWithApplicationOptions (options)
    .Build ();
 
var scopes = new string[] {
    "email",
    "offline_access",
    "https://outlook.office.com/IMAP.AccessAsUser.All", // Only needed for IMAP
    //"https://outlook.office.com/POP.AccessAsUser.All",  // Only needed for POP
    //"https://outlook.office.com/SMTP.Send", // Only needed for SMTP
};

var authToken = await publicClientApplication.AcquireTokenInteractive (scopes).ExecuteAsync ();

var oauth2 = new SaslMechanismOAuth2 (authToken.Account.Username, authToken.AccessToken);

using (var client = new ImapClient ()) {
    await client.ConnectAsync ("outlook.office365.com", 993, SecureSocketOptions.SslOnConnect);
    await client.AuthenticateAsync (oauth2);
    await client.DisconnectAsync (true);
}

Upvotes: 7

cfitzer
cfitzer

Reputation: 93

You can use the EWS managed api by creating an OAuthCredentials object using the OAuth token and then setting the credentials and endpoint on an ExchangeService object. You can then use the ExchangeService object to create and send the email.

var credentials = new OAuthCredentials(token);
var ews = new ExchangeService();
ews.Credentials = credentials;
ews.Url = endpointUrl;

var email = new EmailMessage(ews);
...

email.Send();

https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/ews-managed-api-reference-for-exchange

The go forward method would be Microsoft Graph, but I'm not as familiar with it. https://learn.microsoft.com/en-us/graph/api/resources/mail-api-overview?view=graph-rest-1.0

Upvotes: 2

Related Questions