user2171002
user2171002

Reputation: 101

Microsoft 365 - SMTP Oauth 2 Authentication error

I am developing an application in Xamarin Android using .NET Standard 2.0. I need to send emails to users within my organization at a certain time. I am trying to implement OAuth 2 authentication since basic authentication will no longer be feasible in Microsoft.

I obtain a token correctly, but when I try to send the email, I get an error: "MailKit.Security.AuthenticationException: 535: 5.7.3 Authentication unsuccessful."

I can't figure out what I'm doing wrong. Could you please help me? Here are two versions of the code I have for sending the email; neither of them works and both give me the same error.

using System;
using System.Threading.Tasks;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
using Microsoft.Identity.Client;

namespace TancarOFs.Services
{
    public class EmailService2
    {

        private static string[] scopes = new string[] { "https://outlook.office365.com/.default" };
        private static readonly string tenantId = "AAAAAAA";
        private static readonly string clientId = "BBBBBBBBB";
        private static readonly string clientSecret = "CCCCCCC";

        public async Task SendEmailAsync(string to, string cc, string subject, string body)
        {
            try
            {
                var confidentialClient = ConfidentialClientApplicationBuilder.Create(clientId)
                        .WithClientSecret(clientSecret)
                        .WithAuthority(new Uri($"https://login.microsoftonline.com/{tenantId}"))
                    .Build();

                var authResult = await confidentialClient.AcquireTokenForClient(scopes).ExecuteAsync();

                var message = new MimeMessage();
                message.From.Add(new MailboxAddress("no-reply", "[email protected]"));
                //message.To.Add(new MailboxAddress(to, to));

                foreach (var recipient in to.Replace(" ", "").Split(new[] { ',', ';' }))
                {
                    message.To.Add(new MailboxAddress(recipient, recipient));
                }

                if (cc != null)
                {
                    foreach (var copy in cc.Replace(" ", "").Split(new[] { ',', ';' }))
                    {
                        message.Cc.Add(new MailboxAddress(copy, copy));
                    }
                }


                message.Subject = subject;
                message.Body = new TextPart("plain") { Text = body };

                using (var client = new SmtpClient())
                {
                    await client.ConnectAsync("smtp.office365.com", 587, SecureSocketOptions.StartTls);
                    client.Authenticate(new SaslMechanismOAuth2("[email protected]", authResult.AccessToken));
                    await client.SendAsync(message);
                    await client.DisconnectAsync(true);
                }
            }
            catch (Exception e)
            {

                throw;
            }
        }
    }
}

Aqui otra versión con el mismo error

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Net.Http;
using System.Threading.Tasks;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;

namespace TancarOFs.Services
{
    public class EmailService
    {

        private string _scope = "https://outlook.office365.com/.default";
        private static readonly string TenantId = "AAAAAAAA";
        private static readonly string _clientId = "BBBBBBBBBB";
        private static readonly string _clientSecret = "CCCCCCCC";
        private static readonly string _username = "[email protected]";

        public async Task SendEmailAsync(string to, string cc, string subject, string body)
        {

            try
            {
                var token = await GetAccessTokenAsync("");

                var message = new MimeMessage();
                message.From.Add(new MailboxAddress("no-reply", _username));
                //message.To.Add(new MailboxAddress(to, to));

                foreach (var recipient in to.Replace(" ", "").Split(new[] { ',', ';' }))
                {
                    message.To.Add(new MailboxAddress(recipient, recipient));
                }

                if (cc != null)
                {
                    foreach (var copy in cc.Replace(" ", "").Split(new[] { ',', ';' }))
                    {
                        message.Cc.Add(new MailboxAddress(copy, copy));
                    }
                }


                message.Subject = subject;
                message.Body = new TextPart("plain") { Text = body };

                using (var client = new SmtpClient())
                {
                    await client.ConnectAsync("smtp.office365.com", 587, SecureSocketOptions.StartTls);
                    await client.AuthenticateAsync(new SaslMechanismOAuth2(_username, token));
                    await client.SendAsync(message);
                    await client.DisconnectAsync(true);
                }
            }
            catch (Exception e)
            {
                throw;
            }

            
        }
        private async Task<string> GetAccessTokenAsync(string code)
        {
            var request = new HttpRequestMessage(HttpMethod.Post, $"https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/token");

            request.Content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("client_id", _clientId),
                new KeyValuePair<string, string>("client_secret", _clientSecret),
                new KeyValuePair<string, string>("grant_type", "client_credentials"),
                new KeyValuePair<string, string>("scope", _scope)
            });

            var client = new HttpClient();
            var response = await client.SendAsync(request);
            var content = await response.Content.ReadAsStringAsync();

            var tokenResponse = JsonDocument.Parse(content);
            return tokenResponse.RootElement.GetProperty("access_token").GetString();
        }
    }
}

I forgot to mention that I have created the application in Azure AD with several permissions, but it still doesn't work.

Azure AD Application permissions

Thanks in advance

Upvotes: 0

Views: 32

Answers (0)

Related Questions