diff --git a/Common/Utils/AuthUtils.cs b/Common/Utils/AuthUtils.cs
index 9c135b3..584a4ef 100644
--- a/Common/Utils/AuthUtils.cs
+++ b/Common/Utils/AuthUtils.cs
@@ -9,6 +9,8 @@ namespace Microsoft.Intune.PowerShellGraphSDK
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
+ using System.Security.Cryptography;
+ using System.Security.Cryptography.X509Certificates;
internal static partial class AuthUtils
{
@@ -49,6 +51,53 @@ internal static partial class AuthUtils
///
internal static bool UseMsiAuth => !string.IsNullOrWhiteSpace(ManagedServiceIdentityEndpoint) && LatestAdalAuthResult == null;
+ ///
+ /// Authenticates with the currently set environment parameters and the provided client certificate identified by thumbprint.
+ ///
+ /// The client secret
+ /// The authentication result.
+ internal static SdkAuthResult AuthWithCertificateThumbprint(string certificateThumbprint)
+ {
+ // Get the environment parameters
+ EnvironmentParameters environmentParameters = AuthUtils.CurrentEnvironmentParameters;
+
+ // Create auth context that we will use to connect to the AAD endpoint
+ AuthenticationContext authContext = new AuthenticationContext(environmentParameters.AuthUrl);
+
+ // Get certificate with specified Thumbprint from "My" store
+ X509Certificate2 xCertificate = null;
+
+ using (X509Store xStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
+ {
+ xStore.Open(OpenFlags.ReadOnly);
+ // Get unexpired certificates with the specified name.
+ X509Certificate2Collection unexpiredCerts = xStore.Certificates
+ .Find(X509FindType.FindByTimeValid, DateTime.Now, false)
+ .Find(X509FindType.FindByThumbprint, certificateThumbprint, false);
+ if (unexpiredCerts == null)
+ throw new Exception($"{certificateThumbprint} certificate was not found or has expired.");
+ // Only return current cert.
+ xCertificate = unexpiredCerts
+ .OfType()
+ .OrderByDescending(c => c.NotBefore)
+ .FirstOrDefault();
+ }
+
+ // Build clientAssertionCertificate for the request
+ ClientAssertionCertificate clientAssertionCertificate = new ClientAssertionCertificate(CurrentEnvironmentParameters.AppId, xCertificate);
+
+ // Acquire token for Microsoft Graph via certificate credentials from AAD
+ AuthenticationResult authenticationResult = authContext.AcquireTokenAsync(CurrentEnvironmentParameters.GraphBaseAddress, clientAssertionCertificate).GetAwaiter().GetResult();
+
+ // Convert the auth result into our own type
+ SdkAuthResult authResult = authenticationResult.ToSdkAuthResult();
+
+ // Save the auth result
+ AuthUtils.LatestAdalAuthResult = authResult;
+
+ return authResult;
+ }
+
///
/// Authenticates with the currently set environment parameters and the provided client secret.
///
diff --git a/PowerShellCmdlets/Utils/UtilCmdlets.cs b/PowerShellCmdlets/Utils/UtilCmdlets.cs
index 1778875..116cf50 100644
--- a/PowerShellCmdlets/Utils/UtilCmdlets.cs
+++ b/PowerShellCmdlets/Utils/UtilCmdlets.cs
@@ -33,6 +33,11 @@ public class Connect : PSCmdlet
///
private const string ParameterSetAdminConsent = "AdminConsent";
+ ///
+ /// Parameter set for triggering the app-only authentication with a client certificate.
+ ///
+ private const string ParameterSetCertificateThumbprint = "CertificateThumbprint";
+
///
/// Parameter set for triggering app-only authentication.
///
@@ -87,6 +92,14 @@ public class Connect : PSCmdlet
[Parameter(ParameterSetName = ParameterSetAppOnly)]
public string ClientSecret { get; set; }
+ ///
+ ///
+ /// If the certificate thumbprint is set, app-only authentication will be performed using the client ID specified by the AppId environment parameter.
+ ///
+ ///
+ [Parameter(ParameterSetName = ParameterSetCertificateThumbprint)]
+ public string CertificateThumbprint { get; set; }
+
///
///
/// If the AdminConsent flag is set, admin consent can be granted for the currently selected AppId
@@ -125,6 +138,12 @@ protected override void ProcessRecord()
// App-only auth
authResult = AuthUtils.AuthWithClientCredentials(this.ClientSecret);
}
+ else if (this.ParameterSetName == ParameterSetCertificateThumbprint)
+ {
+ authResult = AuthUtils.AuthWithCertificateThumbprint(this.CertificateThumbprint);
+
+ }
+
else
{
// User auth
diff --git a/PowerShellGraphSDK.csproj b/PowerShellGraphSDK.csproj
index 8c88de7..5e6fdb6 100644
--- a/PowerShellGraphSDK.csproj
+++ b/PowerShellGraphSDK.csproj
@@ -41,9 +41,9 @@
-
-
-
+
+
+
all
runtime; build; native; contentfiles; analyzers
@@ -90,7 +90,7 @@
-
+