I am trying to replace a windows service which sends emails for users via smtp with Microsoft accounts (within the business)
Microsoft are turning off the old auth method at the end of the month
I am using c# and mail kit and can get a token, however I can not currently send emails without user interaction to 'sign in via a webpage' each time to grant permission
Ofcourse a windows service on another box can not interact with the users
I have registered my app via azure, that part seems done
I have searched the web and find a lot of mixed results
Is anyone aware, Is it currently possible to have a windows service (without user interaction) send emails on a users behalf (I have their user/pass etc) but can not see a clear way to do this using mailkit
Thank You
it appears that user:sendmail has application permission. https://docs.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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.