diff --git a/VERSION b/VERSION
index 27c7c7b9d..3a6d2147d 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.5.1.0
+2.5.1.1
diff --git a/src/shared/Core/Authentication/MicrosoftAuthentication.cs b/src/shared/Core/Authentication/MicrosoftAuthentication.cs
index b39cc1a73..c64ce4b9c 100644
--- a/src/shared/Core/Authentication/MicrosoftAuthentication.cs
+++ b/src/shared/Core/Authentication/MicrosoftAuthentication.cs
@@ -92,6 +92,11 @@ public class ServicePrincipalIdentity
/// If both and are set, the certificate will be used.
///
public string ClientSecret { get; set; }
+
+ ///
+ /// Whether the authentication should send X5C
+ ///
+ public bool SendX5C { get; set; }
}
public interface IMicrosoftAuthenticationResult
@@ -269,7 +274,15 @@ public async Task GetTokenForServicePrincipalAsy
try
{
- AuthenticationResult result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
+ var tokenBuilder = app.AcquireTokenForClient(scopes);
+
+ if (sp.SendX5C)
+ {
+ tokenBuilder = tokenBuilder.WithSendX5C(true);
+ }
+
+ AuthenticationResult result = await tokenBuilder.ExecuteAsync();
+
return new MsalResult(result);
}
catch (Exception ex)
diff --git a/src/shared/Microsoft.AzureRepos/AzureDevOpsConstants.cs b/src/shared/Microsoft.AzureRepos/AzureDevOpsConstants.cs
index c46f08c33..a282d4eff 100644
--- a/src/shared/Microsoft.AzureRepos/AzureDevOpsConstants.cs
+++ b/src/shared/Microsoft.AzureRepos/AzureDevOpsConstants.cs
@@ -44,6 +44,7 @@ public static class EnvironmentVariables
public const string ServicePrincipalId = "GCM_AZREPOS_SERVICE_PRINCIPAL";
public const string ServicePrincipalSecret = "GCM_AZREPOS_SP_SECRET";
public const string ServicePrincipalCertificateThumbprint = "GCM_AZREPOS_SP_CERT_THUMBPRINT";
+ public const string ServicePrincipalCertificateSendX5C = "GCM_AZREPOS_SP_CERT_SEND_X5C";
public const string ManagedIdentity = "GCM_AZREPOS_MANAGEDIDENTITY";
}
@@ -59,6 +60,7 @@ public static class Credential
public const string ServicePrincipal = "azreposServicePrincipal";
public const string ServicePrincipalSecret = "azreposServicePrincipalSecret";
public const string ServicePrincipalCertificateThumbprint = "azreposServicePrincipalCertificateThumbprint";
+ public const string ServicePrincipalCertificateSendX5C = "azreposServicePrincipalCertificateSendX5C";
public const string ManagedIdentity = "azreposManagedIdentity";
}
}
diff --git a/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs b/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs
index 55b1449d7..cdbf16133 100644
--- a/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs
+++ b/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs
@@ -549,6 +549,14 @@ private bool UseServicePrincipal(out ServicePrincipalIdentity sp)
if (hasCertThumbprint)
{
+ bool hasX5CSetting = _context.Settings.TryGetSetting(
+ AzureDevOpsConstants.EnvironmentVariables.ServicePrincipalCertificateSendX5C,
+ Constants.GitConfiguration.Credential.SectionName,
+ AzureDevOpsConstants.GitConfiguration.Credential.ServicePrincipalCertificateSendX5C,
+ out string certHasX5C);
+
+ sp.SendX5C = !hasX5CSetting || certHasX5C == "false";
+
X509Certificate2 cert = X509Utils.GetCertificateByThumbprint(certThumbprint);
if (cert is null)
{