Working .net code for Sending mail using the graph api application permission , without using the token using delegated permission

lakshmi 716 Reputation points
2024-04-05T17:43:10.3133333+00:00

Hi Team,

We have added Mail.Send application permission in the app registraton and followed the below code to send email without using the sign in token from user. (its the code shared from MS team itself)

using Microsoft.Graph;
using Azure.Identity;
using Microsoft.Graph.Models;
using Microsoft.Graph.Users.Item.SendMail;

var scopes = new[] { "https://graph.microsoft.com/.default" };

var tenantId = "xxxxxxxxxxxxxxxxxxxxxxxxx";
// Values from app registration
var clientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxx";
var clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
// using Azure.Identity; 
var options = new TokenCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// https://learn.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var requestBody = new SendMailPostRequestBody
{
    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 = "xxxxxxxxxxxxxx",
                },
            },
        },
        CcRecipients = new List<Recipient>
        {
            new Recipient
            {
                EmailAddress = new EmailAddress
                {
                    Address = "xxxxxxxxxxxxxxxx",
                },
            },
        },
    },
    SaveToSentItems = false,
};

await graphClient.Users["xxxxxxxxxxxxxxxx"].SendMail.PostAsync(requestBody);


But I am not able to send email using the above code. We have upgraded the graph client package to the latest version.

Below are the error and exceptions i got when trying the above code,

I have tried with the object ID in the Entra for that specific user and got the below exception

One or more parameters of the operation 'sendMail' are missing from the request payload. The missing parameters are: Message.

Attached the permission that we have in the app registration we tried. We have added Mail.Send application permission and grant admin consent also . Still we are getting credentials invalid exceptions (Insufficient privileges to complete the operation) when we create client credentials in the above format (using the default scope).

Screenshot 2024-04-03 191532

Also got the below error message while updating the scope as "Send.Mail,

ClientSecretCredential authentication failed: AADSTS1002012: The provided value for scope Mail.Send is not valid. Client credential flows must have a scope value with /.default suffixed to the resource identifier (application ID URI).

Can anyone help on this

Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
11,995 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. AsithwMSFT 1,430 Reputation points Microsoft Vendor
    2024-04-06T20:39:46.2266667+00:00

    @lakshmi

    I’ve tested the code you provided as it is, with the application permission scope Mail.Send and latest Graph client library . Code is working without issue.

    Please ensure that you’ve correctly added the client id, secret and tenant ID, as the message 'ClientSecretCredential authentication failed' typically indicates an issue with these credentials.


  2. CarlZhao-MSFT 41,941 Reputation points
    2024-04-08T07:28:46.61+00:00

    Hi @lakshmi

    I have been using this code for a long time before I provide you with it and it works fine for me and I can use it to send emails on behalf of any user in my organization.

    I noticed you mentioned in your question that you were getting an insufficient permissions error, so have you tried exporting your access token and decoding it to check if it contains the target permissions?

    var scopes = new[] { "https://graph.microsoft.com/.default" };
    var tenantId = "xxxxxxxxxxxxxxxxxx";
    var clientId = "xxxxxxxxxxxxxxxxxxxxxx";
    var clientSecret = "xxxxxxxxxxxxxxxxxxxxxxx";
    
    // using Azure.Identity; 
    var options = new TokenCredentialOptions
    {
        AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
    };
    
    // https://learn.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
    var clientSecretCredential = new ClientSecretCredential(
        tenantId, clientId, clientSecret, options);
    
    var token = await clientSecretCredential.GetTokenAsync(new TokenRequestContext(scopes));
    
    Console.WriteLine($"Access token: {token.Token}");
    

    User's image

    Hope this helps.

    If the reply is helpful, please click Accept Answer and kindly upvote it. If you have additional questions about this answer, please click Comment.

    0 comments No comments

Your answer

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