Background mail sending service using Microsoft account

Aleks Vujić 6 Reputation points
2022-05-30T11:45:21.427+00:00

We are developing a centralized email notifications service (let's call it EmailService) in .NET Core 3.1. Its purpose is to expose a REST API endpoint (ex. POST /SendMail) which will be available to all other company applications. When some application calls /SendMail, it passes fields such as to, cc, subject and htmlBody in JSON format. EmailService then sends the email from Microsoft account to the given emails with specified content. Think of it like no-reply@company.com notification.

Diagram:

DzVo4.png

From this description it is quite obvious that EmailService is some kind of background-running deamon process without user interaction. When its REST API endpoint /SendMail is called, it must authenticate against Microsoft server and send an email to the customer.

We are using MailKit for sending email messages and SMTP client/protocol like this:

   using (var client = new SmtpClient())  
   {  
   	client.Connect ("smtp.friends.com", 587, false);  
     
   	client.Authenticate ("no-reply@company.com", "access_token");  
     
   	client.Send (message);  
   	client.Disconnect (true);  
   }  

I have the following questions:

  1. How should I configure "App registration" inside Azure portal for our use case (daemon background process)?
  2. How should I handle the tokens inside .NET Core application? I assume that there should be some kind of never-expiring(?) refresh_token which can be used to retrieve new access_token when it expires?
  3. We should use https://graph.microsoft.com/SMTP.Send scope, right?
  4. Since EmailService will be a long-running process it should follow the principle: "configure once, work automatically from then on".
Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
10,715 questions
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
19,664 questions
{count} vote

2 answers

Sort by: Most helpful
  1. Shweta Mathur 27,936 Reputation points Microsoft Employee
    2022-05-31T12:44:36.427+00:00

    Hi @Aleks Vujić ,

    Thanks for reaching out.

    I understand you are looking to configure your applications to allow to send e-mails without user context using the Microsoft Graph.

    How should I configure "App registration" inside Azure portal for our use case (daemon background process)?

    For any kind of application, registering the application is quite similar. For background processes as well, you can register the application by navigating to Azure Active Directory->App Registrations->New Registration
    Name: Name of your application you want to choose
    Type: Accounts in this organizational directory only (Single tenant) or based on scenario if there is multi tenant organization.
    Redirect URI: Not required.

    Create a client secret and store the value of secret at safe location.
    Copy the ClientId, TenantId and ClientSecret which is needed to configure the appliciation.

    We should use https://graph.microsoft.com/SMTP.Send scope, right?

    For background processes, where there is no user interaction required, we need to set up application permission rather than delegated permissions.
    You need to add Mail.Send permission as application permission to call send Mail API.

    207132-image.png

    You need to grant admin consent for application permissions by clicking on "Grant Admin Consent for <yourTenant>".

    206928-image.png

    Note: You do not require any third-party relay service like SMTP when you are using Graph API to send emails.

    How should I handle the tokens inside .NET Core application? I assume that there should be some kind of never-expiring(?) refresh_token which can be used to retrieve new access_token when it expires?

    Microsoft Authentication Library (MSAL) provide many ways to acquire and handle the token based on the application type. Client credential flow is used to acquire the token for daemon applications and maintain a token cache which is capable to refresh the token while acquire the token silently.

    Once you will be able to get the access token. You can use GraphServiceClient to send message using sendMail endpoint.

    GraphServiceClient graphClient = new GraphServiceClient( authProvider );

    var message = new Message
    {
    Subject = "Meet for lunch?",
    Body = new ItemBody
    {
    ContentType = BodyType.Text,
    Content = "The new cafeteria is open."
    },
    ToRecipients = new List<Recipient>()
    {
    new Recipient
    {
    EmailAddress = new EmailAddress
    {
    Address = "fannyd@Company portal .onmicrosoft.com"
    }
    }
    },
    CcRecipients = new List<Recipient>()
    {
    new Recipient
    {
    EmailAddress = new EmailAddress
    {
    Address = "danas@Company portal .onmicrosoft.com"
    }
    }
    }
    };

    var saveToSentItems = false;

    await graphClient.Me
    .SendMail(message,saveToSentItems)
    .Request()
    .PostAsync();

    Since EmailService will be a long-running process it should follow the principle: "configure once, work automatically from then on".

    MSAL manages the token silently and cache the token which also refresh the token when token is about to expire to maintain the session thoroughly.

    Hope this will help.

    Thanks,
    Shweta

    ----------------------------------------

    Please remember to "Accept Answer" if answer helped you.