it appears that user:sendmail has application permission.
https://learn.microsoft.com/en-us/graph/api/user-sendmail?view=graph-rest-1.0&tabs=http
meaning you can register your application with a client secret and then use the client secret to make calls to graph without the need for user interaction.
you can most of this from the graph quick start https://developer.microsoft.com/en-us/graph/quick-start
I am working on something similar where I am making graph calls through a c# api but probably similiar.
I have my registration info in appsettings.
"Settings": {
"clientId": "7d202de8-ccd8-xxxxxxxx-a5e4-101df736dd6a",
"clientSecret": "ctV8Q~U3qYHpd_xxxxxxOeHB08TXxxxxxxxxU_.ag9",
"tenantId": "44fxxxxxx5-327a-4d5a-86d5-cxxxxxxxxx97d7e4"
},
I have a helper class that makes the api calls (this one is getting some
users)
namespace Application
{
using Azure.Identity;
using Microsoft.Graph;
public class GraphHelper
{
private static Settings _settings;
public static void InitializeGraph(Settings settings,
Func<DeviceCodeInfo, CancellationToken, Task> deviceCodePrompt)
{
_settings = settings;
}
private static ClientSecretCredential _clientSecretCredential;
private static GraphServiceClient _appClient;
private static void EnsureGraphForAppOnlyAuth()
{
_ = _settings ??
throw new System.NullReferenceException("Settings cannot be null");
if (_clientSecretCredential == null)
{
_clientSecretCredential = new ClientSecretCredential(
_settings.TenantId, _settings.ClientId, _settings.ClientSecret);
}
if (_appClient == null)
{
_appClient = new GraphServiceClient(_clientSecretCredential,
new[] { "https://graph.microsoft.com/.default" });
}
}
public static Task<IGraphServiceUsersCollectionPage> GetUsersAsync()
{
EnsureGraphForAppOnlyAuth();
_ = _appClient ??
throw new System.NullReferenceException("Graph has not been initialized for app-only auth");
return _appClient.Users
.Request()
.Select(u => new
{
// Only request specific properties
u.DisplayName,
u.Id,
u.Mail
})
// Get at most 25 results
.Top(25)
// Sort by display name
.OrderBy("DisplayName")
.GetAsync();
}
}
}
then I can make calls to it like this
public async Task<IGraphServiceUsersCollectionPage> Handle(Query request, CancellationToken cancellationToken)
{
Settings s = new Settings();
var settings = s.LoadSettings(_config);
GraphHelper.InitializeGraph(settings, (info, cancel) => Task.FromResult(0));
var result = await GraphHelper.GetUsersAsync();
return result;
}