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

lakshmi 816 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 Security Microsoft Graph
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. CarlZhao-MSFT 46,366 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.

    1 person found this answer helpful.

  2. AsithwMSFT 1,445 Reputation points Microsoft External Staff
    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.


  3. David Garavit 0 Reputation points
    2025-03-11T00:13:36.33+00:00

    Hi,

    I have tried to use exactly the same code you are using, and I do have issues as well.

    The difference is the error message I'm getting:

    System.InvalidOperationException: 'Content type text/html does not have a factory registered to be parsed'

    If I decode my token as CarlZhao-MSFT suggests, I actually have the send email role:"roles": [ "User.ReadBasic.All", "User.Read.All", "Mail.Send" ],

    So, not sure what is happening

    Have you made it work already?

    regards

    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.