Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
Expand All @@ -206,9 +206,18 @@ public bool SetProvider(SqlAuthenticationMethod authenticationMethod, SqlAuthent
return true;
}

/// <summary>
/// Fetches provided configuration section from app.config file.
/// Does not support reading from appsettings.json yet.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name"></param>
/// <returns></returns>
private static T FetchConfigurationSection<T>(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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -49,6 +49,27 @@ private void InvalidCombinationCheck(SqlCredential credential)
Assert.Throws<InvalidOperationException>(() => connection.AccessToken = "SampleAccessToken");
}
}

#if NETFRAMEWORK
// This test is only valid for .NET Framework

/// <summary>
/// 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.
/// </summary>
[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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// 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.
/// </summary>
public class DummySqlAuthenticationProvider : SqlAuthenticationProvider
{
public static string DUMMY_TOKEN_STR = "dummy_access_token";

public override Task<SqlAuthenticationToken> 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<Compile Include="AlwaysEncryptedTests\Utility.cs" />
<Compile Include="AssertExtensions.cs" />
<Compile Include="DataCommon\AssemblyResourceManager.cs" />
<Compile Include="DataCommon\DummySqlAuthenticationProvider.cs" />
<Compile Include="DataCommon\SystemDataResourceManager.cs" />
<Compile Include="DataCommon\TestUtility.cs" />
<Compile Include="LocalizationTest.cs" />
Expand Down Expand Up @@ -71,6 +72,11 @@
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsParserStateObject.Multiplexer.cs" />
<Compile Include="..\..\src\Microsoft\Data\SqlClient\Packet.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetGroup)' == 'netfx'">
<None Update="app.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<!-- XUnit and XUnit extensions -->
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.XUnitExtensions" />
Expand All @@ -91,6 +97,7 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Microsoft.SqlServer.Types" />
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="System.Configuration.ConfigurationManager" />
<PackageReference Include="System.Security.Cryptography.Pkcs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp'">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)]
Expand All @@ -22,5 +22,18 @@ public void DefaultAuthenticationProviders(SqlAuthenticationMethod method)
{
Assert.IsType<ActiveDirectoryAuthenticationProvider>(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<DummySqlAuthenticationProvider>(SqlAuthenticationProvider.GetProvider(method));
}

#endif
}
}
13 changes: 13 additions & 0 deletions src/Microsoft.Data.SqlClient/tests/FunctionalTests/app.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Application configuration file is loaded by the compiler first before loading managed types. -->
<configuration>
<configSections>
<section name="SqlClientAuthenticationProviders" type="Microsoft.Data.SqlClient.SqlClientAuthenticationProviderConfigurationSection,Microsoft.Data.SqlClient" />
</configSections>
<!-- Custom authentication providers from app.config are loaded by the SqlAuthenticationProviderManager before registering default authentication provider. -->
<SqlClientAuthenticationProviders>
<providers>
<add name="active directory interactive" type="Microsoft.Data.SqlClient.FunctionalTests.DataCommon.DummySqlAuthenticationProvider, FunctionalTests" />
</providers>
</SqlClientAuthenticationProviders>
</configuration>
Loading