Gmail Oauth 2 for smtp

Rajesh Kola 0 Reputation points
2025-03-29T06:18:20.99+00:00

I am working on integrating Gmail SMTP using OAuth2 in an ASP.NET Core Web API project. I am looking for a sample project or implementation guide that demonstrates how to configure Gmail's SMTP server with OAuth2 authentication in the context of an ASP.NET Core application.

Here are some details about what I have tried so far:

I have set up OAuth2 credentials in the Google Developer Console.

I am able to authenticate with Gmail but facing issues while sending emails using SMTP with OAuth2.

I have tried using the standard SMTP client library in ASP.NET Core but have been unable to establish a proper connection or send emails.

Can anyone share a sample project or guide on how to properly implement this functionality in ASP.NET Core Web API using Gmail SMTP with OAuth2?

Developer technologies | ASP.NET Core | Other
0 comments No comments

4 answers

Sort by: Most helpful
  1. Danny Nguyen (WICLOUD CORPORATION) 7,425 Reputation points Microsoft External Staff Moderator
    2025-07-15T05:17:03.1166667+00:00

    Hi,

    You should utilize the MailKit library for email operations, combined with Google's Official .NET Client Libraries for handling the OAuth2 flow.

    Here are the essential steps:

    1. Install Required NuGet Packages:
    dotnet add package MailKit
    dotnet add package Google.Apis.Auth
    dotnet add package Google.Apis.Gmail.v1
    
    1. Configure Your Application (appsettings.json)

    Store your Google API credentials and sender information securely.

    {
      "Gmail": {
        "ClientId": "your-google-client-id.apps.googleusercontent.com",
        "ClientSecret": "your-google-client-secret",
        "RefreshToken": "your-previously-obtained-refresh-token",
        "UserEmail": "******@gmail.com"
      },
      "Logging": { /* ... */ }
    }
    

    ClientId and ClientSecret: Obtained from the Google Cloud Console.

    RefreshToken: This is a long-lived token obtained once through an interactive user consent flow. It's used to securely request new, short-lived access tokens without requiring user interaction every time.

    UserEmail: The Gmail address from which emails will be sent.

     

    1. Obtain OAuth2 Access Token

    This method uses the stored refresh token to get a new, valid access token.

    using Google.Apis.Auth.OAuth2;using Google.Apis.Auth.OAuth2.Flows;using Google.Apis.Auth.OAuth2.Responses;using Google.Apis.Gmail.v1; // For GmailService.Scope.GmailSendusing Microsoft.Extensions.Configuration; // For IConfigurationpublic class GmailOAuthService{
        private readonly string _clientId;
        private readonly string _clientSecret;
        private readonly string _refreshToken;
        private readonly string _userEmail;
        public GmailOAuthService(IConfiguration configuration)    {        var gmailConfig = configuration.GetSection("Gmail");
            _clientId = gmailConfig["ClientId"] ?? throw new ArgumentNullException("Gmail:ClientId");
            _clientSecret = gmailConfig["ClientSecret"] ?? throw new ArgumentNullException("Gmail:ClientSecret");
            _refreshToken = gmailConfig["RefreshToken"] ?? throw new ArgumentNullException("Gmail:RefreshToken");
            _userEmail = gmailConfig["UserEmail"] ?? throw new ArgumentNullException("Gmail:UserEmail");
        }
        /// <summary>/// Gets a new OAuth2 access token using the stored refresh token./// </summary>/// <returns>The access token string.</returns>public async Task<string> GetAccessTokenAsync()    {        // Define the scope needed for sending emails via SMTP.// The "https://mail.google.com/" scope is generally preferred for IMAP/POP/SMTP.// While GmailService.Scope.GmailSend works for the Gmail API,// for SMTP authentication, 'https://mail.google.com/' or 'https://www.googleapis.com/auth/gmail.compose'// is often more robust.var scopes = new[] { "https://mail.google.com/" }; // Or new[] { GmailService.Scope.GmailSend } if the latter consistently works for youvar credential = new UserCredential(
                new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
                {
                    ClientSecrets = new ClientSecrets
                    {
                        ClientId = _clientId,
                        ClientSecret = _clientSecret
                    },
                    Scopes = scopes // Set the required scopes
                }),
                _userEmail, // The email address of the user who granted the refresh tokennew TokenResponse
                {
                    RefreshToken = _refreshToken
                }
            );
            // This method will automatically refresh the token if it's expired.await credential.RequestAccessTokenAsync(CancellationToken.None);
            return credential.AccessToken;
        }
        // ... (rest of your MailKit sending logic will go here)
    }
     
    
    1. Send Email with MailKit

     

    This method uses MailKit to connect to Gmail's SMTP server and authenticate with the obtained OAuth2 access token.

    using MimeKit;using MailKit.Net.Smtp;using MailKit.Security;
    public class GmailService // Renamed for clarity, or integrate into GmailOAuthService{
        private readonly GmailOAuthService _oauthService; // Inject the service that gets the tokenprivate readonly string _senderEmail; // From configurationpublic GmailService(GmailOAuthService oauthService, IConfiguration configuration)    {        _oauthService = oauthService;        _senderEmail = configuration.GetSection("Gmail")["UserEmail"] ?? throw new ArgumentNullException("Gmail:UserEmail");
        }
        /// <summary>/// Sends an email via Gmail SMTP using OAuth2 authentication./// </summary>public async Task SendEmailAsync(string toEmail, string subject, string body)    {        // 1. Create the MimeMessagevar message = new MimeMessage();
            message.From.Add(new MailboxAddress("Your Sender Name", _senderEmail));
            message.To.Add(new MailboxAddress("", toEmail)); // Name can be empty if not known        message.Subject = subject;        message.Body = new TextPart("html") { Text = body };
            // 2. Get OAuth2 Access Tokenvar accessToken = await _oauthService.GetAccessTokenAsync();
            // 3. Send via SMTP using MailKitusing var client = new SmtpClient();
            try        {            await client.ConnectAsync("smtp.gmail.com", 587, SecureSocketOptions.StartTls);
                // Google's SMTP uses the SASL XOAUTH2 mechanismvar oauth2 = new SaslMechanismOAuth2(_senderEmail, accessToken);
                await client.AuthenticateAsync(oauth2);
                await client.SendAsync(message);
            }
            catch (Exception ex)
            {
                // Log the exception (e.g., using ILogger)
                Console.WriteLine($"Error sending email: {ex.Message}");
                throw; // Re-throw or handle as appropriate
            }
            finally
            {
                await client.DisconnectAsync(true); // Disconnect and dispose of the client
            }
        }
    }
    
    • SmtpClient: MailKit's SMTP client.
    • SecureSocketOptions.StartTls: Connects on port 587 and then upgrades the connection to TLS.
    • SaslMechanismOAuth2: This is the MailKit class specifically designed to handle Google's (and other providers') SASL XOAUTH2 authentication mechanism. It requires the user's email address and the access token.
    1. Integrate into ASP.NET Core API Controller

     

    Set up Dependency Injection and expose an API endpoint for sending emails.

    using Microsoft.AspNetCore.Mvc;using System.Threading.Tasks;
    // Define a simple request model for the APIpublic class EmailRequest{
        public string ToEmail { get; set; }
        public string Subject { get; set; }
        public string Body { get; set; }
    }
    [ApiController]
    [Route("api/[controller]")]public class EmailController : ControllerBase{
        private readonly GmailService _gmailService; // Or your unified servicepublic EmailController(GmailService gmailService)    {        _gmailService = gmailService;    }
        /// <summary>/// Sends an email via the configured Gmail service./// </summary>    [HttpPost("send")]
        public async Task<IActionResult> SendEmail([FromBody] EmailRequest request)    {        if (!ModelState.IsValid)
            {            return BadRequest(ModelState);
            }
            try
            {
                await _gmailService.SendEmailAsync(request.ToEmail, request.Subject, request.Body);
                return Ok("Email sent successfully.");
            }
            catch (Exception ex)
            {
                // In a production application, log the full exception details// and return a more generic error message to the client for security.return StatusCode(500, $"Failed to send email: {ex.Message}");
            }
        }
    }
    

    ASP.NET Core Controllers: Microsoft Learn - Create web APIs with ASP.NET Core

    Dependency Injection in ASP.NET Core: Microsoft Learn - Dependency injection in ASP.NET Core

     

    1. Configure Dependency Injection (Program.cs or Startup.cs)

     

    Register your services in the ASP.NET Core DI container.
    // In Program.cs (for .NET 6+ Minimal APIs)var builder = WebApplication.CreateBuilder(args);
    // Add services to the container.builder.Services.AddControllers();
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();
    // Register your Gmail servicesbuilder.Services.AddSingleton<GmailOAuthService>(); // For getting the access tokenbuilder.Services.AddScoped<GmailService>();         // Your email sending servicevar app = builder.Build();
    // Configure the HTTP request pipeline.if (app.Environment.IsDevelopment())
    {
        app.UseSwagger();
        app.UseSwaggerUI();
    }
    app.UseHttpsRedirection();
    app.UseAuthorization();
    app.MapControllers();
    app.Run();
    

    Key Differences from Regular SMTP (Username/Password)

     

    • MailKit over SmtpClient: The built-in System.Net.Mail.SmtpClient does not support the necessary OAuth2 authentication mechanisms. MailKit is the industry standard for this.
    • OAuth2 Authentication: Instead of a simple NetworkCredential with username/password, you use SaslMechanismOAuth2 with an access token.
    • Dynamic Access Tokens: Access tokens are short-lived (typically 1 hour). A refresh token is used to dynamically obtain new access tokens, ensuring continuous, secure access without storing static passwords.

    Was this answer helpful?

    1 person found this answer helpful.

  2. Bruce (SqlWork.com) 84,496 Reputation points
    2025-03-29T16:24:49.37+00:00

    The SmtpClient class does not support oauth (as now required by google and Office) and there are currently no plans to add support. You will need to pick another email library. The docs recommend the open source mailkit.

    https://learn.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient?view=net-9.0

    Was this answer helpful?

    0 comments No comments

  3. AgaveJoe 31,361 Reputation points
    2025-03-29T10:21:46.7233333+00:00

    I am working on integrating Gmail SMTP using OAuth2 in an ASP.NET Core Web API project.

    It's important to distinguish between Gmail SMTP and the Gmail API. Gmail SMTP doesn't support OAuth2, but the API does and is intended for programmatic email sending.

    Can anyone share a sample project or guide on how to properly implement this functionality in ASP.NET Core Web API using Gmail SMTP with OAuth2?

    You'll want to start with the Google OAuth developer documentation, it's really thorough and has ASP.NET libraries. Figuring out your OAuth client type is key. For web apps sending email, service accounts are often used, but to give you specific help, I'd need to see your code and understand how your application is set up.

    https://developers.google.com/identity/protocols/oauth2

    Was this answer helpful?

    0 comments No comments

  4. Andrew Velasquez 5 Reputation points
    2025-03-29T08:04:55.69+00:00

    Good Afternoon Rajesh,
    Not exactly what you wanted but here is the google documentation on using the oauth api with .net:
    https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth

    Here is the smtp page with examples in Java and python on sending emails:
    https://developers.google.com/workspace/gmail/api/guides/sending#python

    If there is a specific error or issue you are facing please let me know and I will do my best to assist.

    Hope this helps. If you need further help on this, tag me in a comment. If the suggested response helped you resolve your issue, please 'Accept as answer', so that it can help others in the community looking for help on similar topics.

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.