sp-dev-fx-webparts/samples/react-realtime-incidentdash.../backend/O365Clinic.Function.Webhooks/Helpers/SPAuthenticationManager.cs

77 lines
3.3 KiB
C#

using Microsoft.Identity.Client;
using Microsoft.SharePoint.Client;
using System;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace O365Clinic.Function.Webhooks.Helpers
{
public class SPAuthenticationManager: IDisposable
{
private bool disposedValue;
public ClientContext GetContext(string siteUrl, string clientId, string tenantId, string certificateThumbprint, string tenantBaseUrl)
{
string accessToken = EnsureAccessTokenAsync(clientId, tenantId, certificateThumbprint, tenantBaseUrl).GetAwaiter().GetResult();
ClientContext clientContext = new ClientContext(siteUrl);
clientContext.ExecutingWebRequest +=
delegate (object oSender, WebRequestEventArgs webRequestEventArgs)
{
webRequestEventArgs.WebRequestExecutor.RequestHeaders["Authorization"] =
"Bearer " + accessToken;
};
return clientContext;
}
public async Task<string> EnsureAccessTokenAsync(string clientId, string tenantId, string certificateThumbprint, string tenantBaseUrl)
{
X509Certificate2 certificate = LoadCertificate(certificateThumbprint);
var scopes = new string[] { $"{tenantBaseUrl}/.default" };
IConfidentialClientApplication clientApp = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithCertificate(certificate)
.WithTenantId(tenantId)
.Build();
AuthenticationResult authResult = await clientApp.AcquireTokenForClient(scopes).ExecuteAsync();
string accessToken = authResult.AccessToken;
return accessToken;
}
private X509Certificate2 LoadCertificate(string certificateThumbprint)
{
// Will only be populated correctly when running in the Azure Function host
string certBase64Encoded = Environment.GetEnvironmentVariable("CertificateBase64Encoded", EnvironmentVariableTarget.Process);
if (!string.IsNullOrEmpty(certBase64Encoded))
{
// Azure Function flow
return new X509Certificate2(Convert.FromBase64String(certBase64Encoded),
"",
X509KeyStorageFlags.Exportable |
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.EphemeralKeySet);
}
else
{
// Local flow
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
var certificateCollection = store.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbprint, false);
store.Close();
return certificateCollection.First();
}
}
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
GC.SuppressFinalize(this);
}
}
}