From 14ca60418dc525b30abca05b3eb4bc4d7ff000b4 Mon Sep 17 00:00:00 2001
From: Cheena Malhotra <13396919+cheenamalhotra@users.noreply.github.com>
Date: Fri, 3 Oct 2025 09:39:17 -0700
Subject: [PATCH 1/2] Fix SetProvider to return immediately if user-defined
provider found (#3620)
* Fix SetProvider to return immediately if user-defined provider found
* Include test
* Fix tests
* Remove unwanted changes
* Update config file name
* Rename file back to app.config
* Copy always
* Disable tests for now.
* Fix framework inclusion
* Fix test failures
* Touch ups
* Fix test (continued)
---
.../SqlAuthenticationProviderManager.cs | 11 +++++++-
.../FunctionalTests/AADAuthenticationTests.cs | 23 +++++++++++++++-
.../DummySqlAuthenticationProvider.cs | 27 +++++++++++++++++++
.../Microsoft.Data.SqlClient.Tests.csproj | 6 +++++
.../SqlAuthenticationProviderTest.cs | 15 ++++++++++-
.../tests/FunctionalTests/app.config | 13 +++++++++
6 files changed, 92 insertions(+), 3 deletions(-)
create mode 100644 src/Microsoft.Data.SqlClient/tests/FunctionalTests/DataCommon/DummySqlAuthenticationProvider.cs
create mode 100644 src/Microsoft.Data.SqlClient/tests/FunctionalTests/app.config
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.cs
index e29746dc6c..1fe587720c 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.cs
@@ -186,7 +186,7 @@ public bool SetProvider(SqlAuthenticationMethod authenticationMethod, SqlAuthent
if (candidateMethod == authenticationMethod)
{
_sqlAuthLogger.LogError(nameof(SqlAuthenticationProviderManager), methodName, $"Failed to add provider {GetProviderType(provider)} because a user-defined provider with type {GetProviderType(_providers[authenticationMethod])} already existed for authentication {authenticationMethod}.");
- break;
+ return false; // return here to avoid replacing user-defined provider
}
}
}
@@ -206,9 +206,18 @@ public bool SetProvider(SqlAuthenticationMethod authenticationMethod, SqlAuthent
return true;
}
+ ///
+ /// Fetches provided configuration section from app.config file.
+ /// Does not support reading from appsettings.json yet.
+ ///
+ ///
+ ///
+ ///
private static T FetchConfigurationSection(string name)
{
Type t = typeof(T);
+
+ // TODO: Support reading configuration from appsettings.json for .NET runtime applications.
object section = ConfigurationManager.GetSection(name);
if (section != null)
{
diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs
index 18997a4d86..64ff5b1e7c 100644
--- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs
+++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs
@@ -5,7 +5,7 @@
using System;
using System.Security;
using System.Threading.Tasks;
-using Microsoft.Identity.Client;
+using Microsoft.Data.SqlClient.FunctionalTests.DataCommon;
using Xunit;
namespace Microsoft.Data.SqlClient.Tests
@@ -49,6 +49,27 @@ private void InvalidCombinationCheck(SqlCredential credential)
Assert.Throws(() => connection.AccessToken = "SampleAccessToken");
}
}
+
+ #if NETFRAMEWORK
+ // This test is only valid for .NET Framework
+
+ ///
+ /// Tests whether SQL Auth provider is overridden using app.config file.
+ /// This use case is only supported for .NET Framework applications, as driver doesn't support reading configuration from appsettings.json file.
+ /// In future if need be, appsettings.json support can be added.
+ ///
+ [Fact]
+ public async Task IsDummySqlAuthenticationProviderSetByDefault()
+ {
+ var provider = SqlAuthenticationProvider.GetProvider(SqlAuthenticationMethod.ActiveDirectoryInteractive);
+
+ Assert.NotNull(provider);
+ Assert.Equal(typeof(DummySqlAuthenticationProvider), provider.GetType());
+
+ var token = await provider.AcquireTokenAsync(null);
+ Assert.Equal(token.AccessToken, DummySqlAuthenticationProvider.DUMMY_TOKEN_STR);
+ }
+ #endif
[Fact]
public void CustomActiveDirectoryProviderTest()
diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/DataCommon/DummySqlAuthenticationProvider.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/DataCommon/DummySqlAuthenticationProvider.cs
new file mode 100644
index 0000000000..bb5e2e2e52
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/DataCommon/DummySqlAuthenticationProvider.cs
@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Threading.Tasks;
+
+namespace Microsoft.Data.SqlClient.FunctionalTests.DataCommon
+{
+ ///
+ /// Dummy class to override default Sql Authentication provider in functional tests.
+ /// This type returns a dummy access token and is only used for registration test from app.config file.
+ /// Since no actual connections are intended to be made in Functional tests,
+ /// this type is added by default to validate config file registration scenario.
+ ///
+ public class DummySqlAuthenticationProvider : SqlAuthenticationProvider
+ {
+ public static string DUMMY_TOKEN_STR = "dummy_access_token";
+
+ public override Task AcquireTokenAsync(SqlAuthenticationParameters parameters)
+ => Task.FromResult(new SqlAuthenticationToken(DUMMY_TOKEN_STR, new DateTimeOffset(DateTime.Now.AddHours(2))));
+
+ // Supported authentication modes don't matter for dummy test, but added to demonstrate config file usage.
+ public override bool IsSupported(SqlAuthenticationMethod authenticationMethod)
+ => authenticationMethod == SqlAuthenticationMethod.ActiveDirectoryInteractive;
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj
index 40f04d773d..1dec789c13 100644
--- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj
@@ -25,6 +25,7 @@
+
@@ -71,6 +72,11 @@
+
+
+ Always
+
+
diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlAuthenticationProviderTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlAuthenticationProviderTest.cs
index d41f4b40d1..c15f1a9300 100644
--- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlAuthenticationProviderTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlAuthenticationProviderTest.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Microsoft.Data.SqlClient.FunctionalTests.DataCommon;
using Xunit;
namespace Microsoft.Data.SqlClient.Tests
@@ -11,7 +12,6 @@ public class SqlAuthenticationProviderTest
[Theory]
[InlineData(SqlAuthenticationMethod.ActiveDirectoryIntegrated)]
[InlineData(SqlAuthenticationMethod.ActiveDirectoryPassword)]
- [InlineData(SqlAuthenticationMethod.ActiveDirectoryInteractive)]
[InlineData(SqlAuthenticationMethod.ActiveDirectoryServicePrincipal)]
[InlineData(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow)]
[InlineData(SqlAuthenticationMethod.ActiveDirectoryManagedIdentity)]
@@ -22,5 +22,18 @@ public void DefaultAuthenticationProviders(SqlAuthenticationMethod method)
{
Assert.IsType(SqlAuthenticationProvider.GetProvider(method));
}
+
+ #if NETFRAMEWORK
+ // This test is only valid for .NET Framework
+
+ // Overridden by app.config in this project
+ [Theory]
+ [InlineData(SqlAuthenticationMethod.ActiveDirectoryInteractive)]
+ public void DefaultAuthenticationProviders_Interactive(SqlAuthenticationMethod method)
+ {
+ Assert.IsType(SqlAuthenticationProvider.GetProvider(method));
+ }
+
+ #endif
}
}
diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/app.config b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/app.config
new file mode 100644
index 0000000000..fb7f63f65f
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/app.config
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
From b6eb4308d220bd5bab1d3d7fd880f79366a2d7b3 Mon Sep 17 00:00:00 2001
From: Cheena Malhotra
Date: Fri, 3 Oct 2025 11:03:41 -0700
Subject: [PATCH 2/2] Fix test
---
.../tests/FunctionalTests/AADAuthenticationTests.cs | 1 +
.../tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs
index 64ff5b1e7c..7b1d9a4698 100644
--- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs
+++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs
@@ -6,6 +6,7 @@
using System.Security;
using System.Threading.Tasks;
using Microsoft.Data.SqlClient.FunctionalTests.DataCommon;
+using Microsoft.Identity.Client;
using Xunit;
namespace Microsoft.Data.SqlClient.Tests
diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj
index 1dec789c13..d788ea079a 100644
--- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj
@@ -138,7 +138,7 @@
-
+