From b302fb791125156dfa8faf9783516eb87cf519cf Mon Sep 17 00:00:00 2001 From: Michal Hanzlik Date: Wed, 4 Oct 2023 13:41:22 +0200 Subject: [PATCH] Support SN+I authentication with AAD for CertificateServiceClientCredentialsFactory --- ...tificateServiceClientCredentialsFactory.cs | 32 ++++++++++++------- ...ateServiceClientCredentialsFactoryTests.cs | 1 + 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/libraries/Microsoft.Bot.Connector/Authentication/CertificateServiceClientCredentialsFactory.cs b/libraries/Microsoft.Bot.Connector/Authentication/CertificateServiceClientCredentialsFactory.cs index 0b52de3b27..5243ec00df 100644 --- a/libraries/Microsoft.Bot.Connector/Authentication/CertificateServiceClientCredentialsFactory.cs +++ b/libraries/Microsoft.Bot.Connector/Authentication/CertificateServiceClientCredentialsFactory.cs @@ -16,11 +16,8 @@ namespace Microsoft.Bot.Connector.Authentication /// public class CertificateServiceClientCredentialsFactory : ServiceClientCredentialsFactory { - private readonly X509Certificate2 _certificate; + private readonly CertificateAppCredentials _certificateAppCredentials; private readonly string _appId; - private readonly string _tenantId; - private readonly HttpClient _httpClient; - private readonly ILogger _logger; /// /// Initializes a new instance of the class. @@ -30,7 +27,16 @@ public class CertificateServiceClientCredentialsFactory : ServiceClientCredentia /// The oauth token tenant. /// A custom httpClient to use. /// A logger instance to use. - public CertificateServiceClientCredentialsFactory(X509Certificate2 certificate, string appId, string tenantId = null, HttpClient httpClient = null, ILogger logger = null) + /// A flag if CertificateAppCredentials should send certificate chains in the request. + /// It enables authentication with AAD using certificate subject name (not CNAME) and issuer instead of a thumbprint. + /// + public CertificateServiceClientCredentialsFactory( + X509Certificate2 certificate, + string appId, + string tenantId = null, + HttpClient httpClient = null, + ILogger logger = null, + bool sendX5c = false) : base() { if (string.IsNullOrWhiteSpace(appId)) @@ -38,11 +44,16 @@ public CertificateServiceClientCredentialsFactory(X509Certificate2 certificate, throw new ArgumentNullException(nameof(appId)); } - _certificate = certificate ?? throw new ArgumentNullException(nameof(certificate)); _appId = appId; - _tenantId = tenantId; - _httpClient = httpClient; - _logger = logger; + + // Instance must be reused otherwise it will cause throttling on AAD. + _certificateAppCredentials = new CertificateAppCredentials( + certificate ?? throw new ArgumentNullException(nameof(certificate)), + sendX5c, + appId, + tenantId, + httpClient, + logger); } /// @@ -67,8 +78,7 @@ public override Task CreateCredentialsAsync( throw new InvalidOperationException("Invalid Managed ID."); } - return Task.FromResult( - new CertificateAppCredentials(_certificate, _appId, _tenantId, _httpClient, _logger)); + return Task.FromResult(_certificateAppCredentials); } } } diff --git a/tests/Microsoft.Bot.Connector.Tests/Authentication/CertificateServiceClientCredentialsFactoryTests.cs b/tests/Microsoft.Bot.Connector.Tests/Authentication/CertificateServiceClientCredentialsFactoryTests.cs index e1bf5ed6bc..d76a54bd3b 100644 --- a/tests/Microsoft.Bot.Connector.Tests/Authentication/CertificateServiceClientCredentialsFactoryTests.cs +++ b/tests/Microsoft.Bot.Connector.Tests/Authentication/CertificateServiceClientCredentialsFactoryTests.cs @@ -27,6 +27,7 @@ public void ConstructorTests() _ = new CertificateServiceClientCredentialsFactory(certificate.Object, TestAppId, tenantId: TestTenantId); _ = new CertificateServiceClientCredentialsFactory(certificate.Object, TestAppId, logger: logger.Object); _ = new CertificateServiceClientCredentialsFactory(certificate.Object, TestAppId, httpClient: new HttpClient()); + _ = new CertificateServiceClientCredentialsFactory(certificate.Object, TestAppId, httpClient: new HttpClient(), sendX5c: true); } [Fact]