1

I am using Graph API to send emails and using clientID, Secret and APPID. I'm getting the token, but I'm unable to send emails:

Code: NoPermissionsInAccessToken Message: The token contains no permissions, or permissions can not be understood. Inner error: AdditionalData: requestId: 53f1cddb-4f38-4efa-ab62-624b495374f0 date: 2020-12-02T10:46:42 ClientRequestId: 53f1cddb-4f38-4efa-ab62-624b495374f0

I have added API permission as delegated to mail.send

IPublicClientApplication publicclientapplication = PublicClientApplicationBuilder
                     .Create(clientId)
                     .WithTenantId(tenantId)
                     .Build();
             
           UsernamePasswordProvider authprovider = new UsernamePasswordProvider(publicclientapplication,scopes);

            var authResult = await publicclientapplication
                    .AcquireTokenByUsernamePassword(scopes, username, passwordstring(stringpassword))
                    .ExecuteAsync().ConfigureAwait(false);
            return authResult.AccessToken;

Code that I'm using to send is:

await graphServiceClient.Me .SendMail(email, false) .Request() .PostAsync();
User123
  • 17
  • 6

1 Answers1

0

Please note that delegated permission is for app+user authentication while application permission is for app-only authentication.

You should have used a wrong Microsoft Graph authentication provider or you have added a wrong type of permission.

Now you should be using Client credentials provider, which uses client credential flow and application permission. But you didn't add application permission in your Azure AD app. It's why you get the error The token contains no permissions. If your application doesn't require a user to sign in, you could use this client credentials provider. But you need to add application permission instead of delegated permission into AAD app and remember to use graphServiceClient.Users["{id or userPrincipalName}"].SendMail to send the mail.

For delegated permission and graphServiceClient.Me endpoint, you should choose Authorization code provider which requires you to implement sign-in interactively. Keep using delegated permission and graphServiceClient.Me.SendMail.

If you don't want to sign in interactively but want to have a user in the access token, you need to choose Username/password provider. But it's not recommended by Microsoft. See Warning here. Keep using delegated permission and graphServiceClient.Me.SendMail as well.

UPDATE:

A sample with Username/password provider:

IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
            .Create(clientId)
            .WithTenantId(tenantID)
            .Build();

UsernamePasswordProvider authProvider = new UsernamePasswordProvider(publicClientApplication, scopes);

GraphServiceClient graphClient = new GraphServiceClient(authProvider);

var email = "Your Username Here";
var str = "Your Password Here";
var password = new SecureString();
foreach (char c in str) password.AppendChar(c);

//prepare message and saveToSentItems here

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

UPDATE 2:

Add application permission Mail.Send into Azure AD app.

IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
    .Create(clientId)
    .WithTenantId(tenantID)
    .WithClientSecret(clientSecret)
    .Build();

ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);

//prepare message and saveToSentItems here

await graphClient.Users["{id or userPrincipalName}"]
    .SendMail(message,saveToSentItems)
    .Request()
    .PostAsync();
Allen Wu
  • 15,529
  • 1
  • 9
  • 20
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/225469/discussion-on-answer-by-allen-wu-microsoft-graph-api-to-send-email-using-token-a). – Samuel Liew Dec 03 '20 at 12:37