2026-07-15

Using Oauth2 to send email via Office365 C#

Stefan Bogdanescu

Stefan Bogdanescu

Founder & Senior Architect

Using Oauth2 to send email via Office365 C#

Sending Emails via Office 365 with OAuth2 in C#: Bridging Tokens to Communication

Sending emails programmatically using modern security protocols like OAuth2, especially when targeting enterprise systems like Office 365 (now Microsoft 365), presents a common hurdle. You've successfully acquired the access token, but the next logical step—how to use that token to actually communicate with the mail service—is often where developers get stuck.

As a senior developer, I can tell you that standard libraries like System.Net.Mail are fundamentally designed for older SMTP authentication methods and do not natively support the complex OAuth2 flows required for interacting with Microsoft Graph or Exchange Online APIs. Therefore, we need to pivot from simple mail transport to making authenticated HTTP calls.

This post will walk you through the correct architectural approach in C# to utilize your OAuth2 token to interact with Office 365 services and send emails effectively.


The Limitations of Traditional Mail Libraries

The primary issue you encountered is correct: System.Net.Mail relies on traditional SMTP credentials or basic authentication. It does not possess the necessary internal logic to handle the OAuth2 token exchange, scope validation, and bearer token transmission required by Microsoft's authorization servers. Trying to force an OAuth token into this framework results in failure because the underlying communication protocol is mismatched.

To achieve true O365 integration, you must interact with the Microsoft Graph API. The Graph API is the gateway to all data and actions within the Microsoft 365 ecosystem. Your access token is the key that unlocks these API endpoints.

The Correct Strategy: Using HttpClient for API Interaction

Since we cannot use built-in mail classes, the robust solution is to leverage the HttpClient class in C# to make direct HTTP requests to the appropriate Microsoft Graph endpoints. This allows you to send authenticated requests using your bearer token.

Step 1: Understanding the Endpoint

To send an email via Office 365, you typically interact with the /sendMail endpoint or use specialized connectors that leverage this authentication. The request structure involves setting the Authorization header with the Bearer Token.

Step 2: C# Implementation Example

The following example demonstrates how to construct an authenticated request using the token you already possess. This assumes you have a valid access token obtained via a successful OAuth flow (e.g., using the Client Credentials flow or Authorization Code flow).

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

public class Office365EmailSender
{
    private readonly string _accessToken;
    private readonly string _graphBaseUrl = "https://graph.microsoft.com/v1.0/";

    public Office365EmailSender(string accessToken)
    {
        _accessToken = accessToken;
    }

    public async Task SendEmailViaGraph(string recipient, string subject, string body)
    {
        using (var client = new HttpClient())
        {
            // Crucial step: Attaching the Bearer Token for authentication
            client.DefaultRequestHeaders.Authorization = 
                new AuthenticationHeaderValue("Bearer", _accessToken);

            // Construct the specific endpoint for sending mail via Graph API
            string emailEndpoint = $"{_graphBaseUrl}users/{recipient}/sendMail";
            
            // Prepare the request content (this part is highly dependent on the exact Graph API method you use)
            var content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("messageType", "appointment"), // Example type
                new KeyValuePair<string, string>("subject", subject),
                new KeyValuePair<string, string>("body", body)
            });

            using (var response = await client.PostAsync(emailEndpoint, content))
            {
                response.EnsureSuccessStatusCode(); // Will throw an exception for 4xx/5xx errors

                string responseBody = await response.Content.ReadAsStringAsync();
                Console.WriteLine("Email sent successfully!");
                Console.WriteLine($"Response: {responseBody}");
            }
        }
    }
}

// Example Usage (assuming you have a token)
/*
public class Program
{
    public static async Task Main(string[] args)
    {
        string myToken = "YOUR_ACQUIRED_ACCESS_TOKEN"; // Replace with your actual token
        var sender = new Office365EmailSender(myToken);

        await sender.SendEmailViaGraph("recipient@example.com", "Test Subject", "This is the body of the email.");
    }
}
*/

Best Practices and Architectural Advice

When dealing with external APIs, especially those involving sensitive tokens, adherence to security best practices is paramount.

  1. Token Expiration: Access tokens expire. You must implement logic to refresh the token using the refresh token you received during the initial OAuth flow before attempting any new API calls.
  2. Secret Management: Never hardcode access tokens in your source code. Use secure environment variables, Azure Key Vault, or dedicated secrets management systems. This is a core principle of secure application development, much like how robust frameworks aim for consistency, similar to the principles guiding large projects in the Laravel ecosystem.
  3. Error Handling: Always check the HTTP status code (response.EnsureSuccessStatusCode()) and parse the response body thoroughly. API calls frequently fail due to scope errors, invalid resource IDs, or expired tokens.

Conclusion

While avoiding third-party services like Mailkit is a valid consideration for simplicity, the most powerful and future-proof solution for sending emails via Office 365 with OAuth2 involves direct interaction with the Microsoft Graph API using HttpClient. By correctly implementing token management and handling HTTP requests, you move beyond simple message transport and achieve true, secure integration within the Microsoft ecosystem. This approach provides the necessary control and security required for enterprise-level applications.

Tags:

Enhance your marketing setup with your own email marketing platform.

Join the growing number of SaaS platforms using Laravel Mail to offer email marketing solutions to their customers.