Update Author field of the list Item in SharePoint online with C# app

For a process I had to update the Author field in SharePoint online list item. This time I decided to use PnP.Core instead of PnP.Framework. Was it worth it? I don't really know, but the method is not the most difficult part of the task.
When I made this method, I created at least 2 solutions. Probably, more, but I did lots of experiments and troubleshooting.
1. with PnP.Core
[HttpGet("updateauthor")]
public async Task<IActionResult> UpdateAuthor()
{
var siteUrl = _settings.SitesSettings.MySite.SiteUrl;
var listTitle = _settings.SitesSettings.MySite.ListTitle;
using (var context = await _pnpContextFactory.CreateAsync(new Uri(siteUrl), _authenticationProvider))
{
var list = await context.Web.Lists.GetByTitleAsync(listTitle);
var item = await list.Items.GetByIdAsync(186, p => p["Author"]);
item.Values["Author"] = 6;
await item.UpdateOverwriteVersionAsync();
await context.ExecuteAsync();
}
return Ok("Authentication updated successfully.");
}
'userId = 6' is my Id at the web. I wanted to be sure that I can update the value.
2. With CSOM
public async Task<IActionResult> SetAuthorCSOMRest(int itemId, int userId)
{
var siteUrl = _settings.SitesSettings.MySite.SiteUrl;
var listTitle = _settings.SitesSettings.MySite.ListTitle;
var clientContext = await _appContext.GetContextAsync(siteUrl);
var listItem = clientContext.Web.Lists.GetByTitle(listTitle).GetItemById(itemId);
clientContext.Load(listItem, i => i["Author"], i => i["Editor"], i=> i["Title"]);
await clientContext.ExecuteQueryAsync();
Microsoft.SharePoint.Client.FieldUserValue userValue = new Microsoft.SharePoint.Client.FieldUserValue()
{
LookupId = userId
};
listItem["Author"] = userValue;
listItem.SystemUpdate();
clientContext.ExecuteQueryAsync();
return Ok($"Author updated successfully for item {itemId} in list {listTitle}.");
}
....
await SetAuthorCSOMRest(187, 6);
Much more interesting is how to make AuthenticationProvider and set the permissions for the App.
I added it into the main Class and registered as a dependency
using PnP.Core.Services;
...
builder.Services.AddSingleton<IAuthenticationProvider>(sp =>
{
var config = sp.GetRequiredService<IConfiguration>();
var settings = sp.GetRequiredService<IOptions<HAppSettings>>().Value;
var vaultUri = $"https://{settings.KeyVaultSettings.VaultName}.vault.azure.net/";
var certName = settings.KeyVaultSettings.CertificateName;
var secretClient = new SecretClient(new Uri(vaultUri), new DefaultAzureCredential());
var secret = secretClient.GetSecret(certName);
var certBytes = Convert.FromBase64String(secret.Value.Value);
var cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(certBytes, "", X509KeyStorageFlags.MachineKeySet);
return new X509CertificateAuthenticationProvider(
settings.KeyVaultSettings.ClientId,
settings.KeyVaultSettings.TenantId,
cert
);
});
The most important thing is that you (your service account) need fullcontrol permissions to the specific site.