Skip to content

Commit d5ba064

Browse files
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)
1 parent c2554ad commit d5ba064

File tree

6 files changed

+92
-3
lines changed

6 files changed

+92
-3
lines changed

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ public bool SetProvider(SqlAuthenticationMethod authenticationMethod, SqlAuthent
186186
if (candidateMethod == authenticationMethod)
187187
{
188188
_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}.");
189-
break;
189+
return false; // return here to avoid replacing user-defined provider
190190
}
191191
}
192192
}
@@ -206,9 +206,18 @@ public bool SetProvider(SqlAuthenticationMethod authenticationMethod, SqlAuthent
206206
return true;
207207
}
208208

209+
/// <summary>
210+
/// Fetches provided configuration section from app.config file.
211+
/// Does not support reading from appsettings.json yet.
212+
/// </summary>
213+
/// <typeparam name="T"></typeparam>
214+
/// <param name="name"></param>
215+
/// <returns></returns>
209216
private static T FetchConfigurationSection<T>(string name)
210217
{
211218
Type t = typeof(T);
219+
220+
// TODO: Support reading configuration from appsettings.json for .NET runtime applications.
212221
object section = ConfigurationManager.GetSection(name);
213222
if (section != null)
214223
{

src/Microsoft.Data.SqlClient/tests/FunctionalTests/AADAuthenticationTests.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
using System;
66
using System.Security;
77
using System.Threading.Tasks;
8-
using Microsoft.Identity.Client;
8+
using Microsoft.Data.SqlClient.FunctionalTests.DataCommon;
99
using Xunit;
1010

1111
namespace Microsoft.Data.SqlClient.Tests
@@ -49,6 +49,27 @@ private void InvalidCombinationCheck(SqlCredential credential)
4949
Assert.Throws<InvalidOperationException>(() => connection.AccessToken = "SampleAccessToken");
5050
}
5151
}
52+
53+
#if NETFRAMEWORK
54+
// This test is only valid for .NET Framework
55+
56+
/// <summary>
57+
/// Tests whether SQL Auth provider is overridden using app.config file.
58+
/// This use case is only supported for .NET Framework applications, as driver doesn't support reading configuration from appsettings.json file.
59+
/// In future if need be, appsettings.json support can be added.
60+
/// </summary>
61+
[Fact]
62+
public async Task IsDummySqlAuthenticationProviderSetByDefault()
63+
{
64+
var provider = SqlAuthenticationProvider.GetProvider(SqlAuthenticationMethod.ActiveDirectoryInteractive);
65+
66+
Assert.NotNull(provider);
67+
Assert.Equal(typeof(DummySqlAuthenticationProvider), provider.GetType());
68+
69+
var token = await provider.AcquireTokenAsync(null);
70+
Assert.Equal(token.AccessToken, DummySqlAuthenticationProvider.DUMMY_TOKEN_STR);
71+
}
72+
#endif
5273

5374
[Fact]
5475
public void CustomActiveDirectoryProviderTest()
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Threading.Tasks;
7+
8+
namespace Microsoft.Data.SqlClient.FunctionalTests.DataCommon
9+
{
10+
/// <summary>
11+
/// Dummy class to override default Sql Authentication provider in functional tests.
12+
/// This type returns a dummy access token and is only used for registration test from app.config file.
13+
/// Since no actual connections are intended to be made in Functional tests,
14+
/// this type is added by default to validate config file registration scenario.
15+
/// </summary>
16+
public class DummySqlAuthenticationProvider : SqlAuthenticationProvider
17+
{
18+
public static string DUMMY_TOKEN_STR = "dummy_access_token";
19+
20+
public override Task<SqlAuthenticationToken> AcquireTokenAsync(SqlAuthenticationParameters parameters)
21+
=> Task.FromResult(new SqlAuthenticationToken(DUMMY_TOKEN_STR, new DateTimeOffset(DateTime.Now.AddHours(2))));
22+
23+
// Supported authentication modes don't matter for dummy test, but added to demonstrate config file usage.
24+
public override bool IsSupported(SqlAuthenticationMethod authenticationMethod)
25+
=> authenticationMethod == SqlAuthenticationMethod.ActiveDirectoryInteractive;
26+
}
27+
}

src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.FunctionalTests.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<Compile Include="AlwaysEncryptedTests\Utility.cs" />
2525
<Compile Include="AssertExtensions.cs" />
2626
<Compile Include="DataCommon\AssemblyResourceManager.cs" />
27+
<Compile Include="DataCommon\DummySqlAuthenticationProvider.cs" />
2728
<Compile Include="DataCommon\SystemDataResourceManager.cs" />
2829
<Compile Include="DataCommon\TestUtility.cs" />
2930
<Compile Include="LocalizationTest.cs" />
@@ -67,6 +68,11 @@
6768
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsParserStateObject.Multiplexer.cs" />
6869
<Compile Include="..\..\src\Microsoft\Data\SqlClient\Packet.cs" />
6970
</ItemGroup>
71+
<ItemGroup Condition="'$(TargetGroup)' == 'netfx'">
72+
<None Update="app.config">
73+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
74+
</None>
75+
</ItemGroup>
7076
<!-- XUnit and XUnit extensions -->
7177
<ItemGroup>
7278
<PackageReference Include="Microsoft.DotNet.XUnitExtensions" />

src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlAuthenticationProviderTest.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using Microsoft.Data.SqlClient.FunctionalTests.DataCommon;
56
using Xunit;
67

78
namespace Microsoft.Data.SqlClient.Tests
@@ -11,7 +12,6 @@ public class SqlAuthenticationProviderTest
1112
[Theory]
1213
[InlineData(SqlAuthenticationMethod.ActiveDirectoryIntegrated)]
1314
[InlineData(SqlAuthenticationMethod.ActiveDirectoryPassword)]
14-
[InlineData(SqlAuthenticationMethod.ActiveDirectoryInteractive)]
1515
[InlineData(SqlAuthenticationMethod.ActiveDirectoryServicePrincipal)]
1616
[InlineData(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow)]
1717
[InlineData(SqlAuthenticationMethod.ActiveDirectoryManagedIdentity)]
@@ -22,5 +22,18 @@ public void DefaultAuthenticationProviders(SqlAuthenticationMethod method)
2222
{
2323
Assert.IsType<ActiveDirectoryAuthenticationProvider>(SqlAuthenticationProvider.GetProvider(method));
2424
}
25+
26+
#if NETFRAMEWORK
27+
// This test is only valid for .NET Framework
28+
29+
// Overridden by app.config in this project
30+
[Theory]
31+
[InlineData(SqlAuthenticationMethod.ActiveDirectoryInteractive)]
32+
public void DefaultAuthenticationProviders_Interactive(SqlAuthenticationMethod method)
33+
{
34+
Assert.IsType<DummySqlAuthenticationProvider>(SqlAuthenticationProvider.GetProvider(method));
35+
}
36+
37+
#endif
2538
}
2639
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<!-- Application configuration file is loaded by the compiler first before loading managed types. -->
3+
<configuration>
4+
<configSections>
5+
<section name="SqlClientAuthenticationProviders" type="Microsoft.Data.SqlClient.SqlClientAuthenticationProviderConfigurationSection,Microsoft.Data.SqlClient" />
6+
</configSections>
7+
<!-- Custom authentication providers from app.config are loaded by the SqlAuthenticationProviderManager before registering default authentication provider. -->
8+
<SqlClientAuthenticationProviders>
9+
<providers>
10+
<add name="active directory interactive" type="Microsoft.Data.SqlClient.FunctionalTests.DataCommon.DummySqlAuthenticationProvider, FunctionalTests" />
11+
</providers>
12+
</SqlClientAuthenticationProviders>
13+
</configuration>

0 commit comments

Comments
 (0)