-
Notifications
You must be signed in to change notification settings - Fork 330
Tests | Cleanup AAD Password auth from tests + code cleanup #4390
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
cheenamalhotra
wants to merge
14
commits into
main
Choose a base branch
from
dev/cheena/aad-test-improvements
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 10 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
bcbac46
Tests | Cleanup AAD Password auth from tests + code cleanup
cheenamalhotra 62e88a8
Fix build
cheenamalhotra 18f879c
Update references
cheenamalhotra 8153957
More updates
cheenamalhotra 29d4617
Fix compiler errors for net462
cheenamalhotra 60262cd
Fix error
cheenamalhotra 7119636
Fix failing test
cheenamalhotra 4185ce8
Fix tests
cheenamalhotra f8f1c89
Fix TestCustomProviderAuthentication
cheenamalhotra 4b40fcc
Address comments
cheenamalhotra 853ffb6
Remove unused AADAuthorityURL config as well
cheenamalhotra eb45a36
Changes from feedback
cheenamalhotra a535d7b
Update Azure config, cleanup
cheenamalhotra f8e3829
CI changes
cheenamalhotra File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
| // new unit and/or integration tests in the future. | ||
|
|
||
| using System.Text.RegularExpressions; | ||
| using Microsoft.Data.SqlClient.Tests.Common; | ||
|
|
||
| namespace Microsoft.Data.SqlClient.Extensions.Azure.Test; | ||
|
|
||
|
|
@@ -28,43 +29,49 @@ public static void KustoDatabaseTest() | |
|
|
||
| [ConditionalFact( | ||
| typeof(Config), | ||
| nameof(Config.HasPasswordConnectionString), | ||
| nameof(Config.HasAzureSqlConnectionString), | ||
| nameof(Config.HasServicePrincipal))] | ||
| public static void NoCredentialsActiveDirectoryServicePrincipal() | ||
| { | ||
| // test Passes with correct connection string. | ||
| string[] removeKeys = { "Authentication", "User ID", "Password", "UID", "PWD" }; | ||
| string connStr = RemoveKeysInConnStr(Config.PasswordConnectionString, removeKeys) + | ||
| $"Authentication=Active Directory Service Principal; User ID={Config.ServicePrincipalId}; PWD={Config.ServicePrincipalSecret};"; | ||
| ConnectAndDisconnect(connStr); | ||
| string connString = Config.AzureSqlConnString | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can just modify the TCP connection string as needed in each test.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| .AddServicePrincipalAuthenticationToConnString() | ||
| .AddUserToConnString(Config.ServicePrincipalId) | ||
| .AddPasswordToConnString(Config.ServicePrincipalSecret); | ||
|
|
||
| ConnectAndDisconnect(connString); | ||
|
|
||
| // connection fails with expected error message. | ||
| string[] credKeys = { "Authentication", "User ID", "Password", "UID", "PWD" }; | ||
| string connStrWithNoCred = RemoveKeysInConnStr(Config.PasswordConnectionString, credKeys) + | ||
| "Authentication=Active Directory Service Principal;"; | ||
| InvalidOperationException e = Assert.Throws<InvalidOperationException>(() => ConnectAndDisconnect(connStrWithNoCred)); | ||
| string connStrWithNoCred = Config.AzureSqlConnString | ||
| .AddServicePrincipalAuthenticationToConnString(); | ||
|
|
||
| InvalidOperationException e = Assert.Throws<InvalidOperationException> | ||
| (() => ConnectAndDisconnect(connStrWithNoCred)); | ||
|
|
||
| string expectedMessage = "Either Credential or both 'User ID' and 'Password' (or 'UID' and 'PWD') connection string keywords must be specified, if 'Authentication=Active Directory Service Principal'."; | ||
| Assert.Contains(expectedMessage, e.Message); | ||
| } | ||
|
|
||
| [ConditionalTheory( | ||
| typeof(Config), | ||
| nameof(Config.HasPasswordConnectionString), | ||
| nameof(Config.HasAzureSqlConnectionString), | ||
| nameof(Config.HasUserManagedIdentityClientId))] | ||
| [InlineData("2445343 2343253")] | ||
| [InlineData("2445343$#^@@%2343253")] | ||
| public static void ActiveDirectoryManagedIdentityWithInvalidUserIdMustFail(string userId) | ||
| { | ||
| // connection fails with expected error message. | ||
| string[] credKeys = { "Authentication", "User ID", "Password", "UID", "PWD" }; | ||
| string connStrWithNoCred = RemoveKeysInConnStr(Config.PasswordConnectionString, credKeys) + | ||
| $"Authentication=Active Directory Managed Identity; User Id={userId}"; | ||
| string connStrWithNoCred = Config.AzureSqlConnString | ||
| .AddManagedIdentityAuthenticationToConnString() | ||
| .AddUserToConnString(userId); | ||
|
|
||
| SqlException e = Assert.Throws<SqlException>(() => ConnectAndDisconnect(connStrWithNoCred)); | ||
|
|
||
| // The Azure.Identity surface message can vary across SDK versions and | ||
| // platforms, so assert on the stable driver-emitted error that proves | ||
| // the managed-identity auth path was taken and failed. | ||
| Regex expected = new( | ||
| @"(\[Managed Identity\]|ManagedIdentityCredential) Authentication unavailable", | ||
| @"Failed to authenticate the user.*Authentication=ActiveDirectoryManagedIdentity", | ||
| RegexOptions.IgnoreCase); | ||
|
|
||
| Assert.Matches(expected, e.GetBaseException().Message); | ||
|
|
@@ -73,13 +80,13 @@ public static void ActiveDirectoryManagedIdentityWithInvalidUserIdMustFail(strin | |
| [ConditionalFact( | ||
| typeof(Config), | ||
| nameof(Config.OnAdoPool), | ||
| nameof(Config.HasPasswordConnectionString), | ||
| nameof(Config.HasAzureSqlConnectionString), | ||
| nameof(Config.HasUserManagedIdentityClientId))] | ||
| public static void ActiveDirectoryDefaultMustPass() | ||
| { | ||
| string[] credKeys = { "Authentication", "User ID", "Password", "UID", "PWD" }; | ||
| string connStr = RemoveKeysInConnStr(Config.PasswordConnectionString, credKeys) + | ||
| $"Authentication=ActiveDirectoryDefault;User ID={Config.UserManagedIdentityClientId};"; | ||
| string connStr = Config.AzureSqlConnString | ||
| .AddAADDefaultAuthenticationToConnString() | ||
| .AddUserToConnString(Config.UserManagedIdentityClientId); | ||
|
|
||
| // Connection should be established using Managed Identity by default. | ||
| ConnectAndDisconnect(connStr); | ||
|
|
@@ -105,35 +112,36 @@ public static void ActiveDirectoryDefaultMustPass() | |
| public static void ADIntegratedUsingSSPI() | ||
| { | ||
| // test Passes with correct connection string. | ||
| string[] removeKeys = { "Authentication", "User ID", "Password", "UID", "PWD", "Trusted_Connection", "Integrated Security" }; | ||
| string connStr = RemoveKeysInConnStr(Config.TcpConnectionString, removeKeys) + | ||
| $"Authentication=Active Directory Integrated;"; | ||
| string connStr = Config.TcpConnectionString | ||
| .RemoveAuthAndCredsProperties() | ||
| .AddAADIntegratedAuthenticationToConnString(); | ||
| ConnectAndDisconnect(connStr); | ||
| } | ||
|
|
||
| [ConditionalFact( | ||
| typeof(Config), | ||
| nameof(Config.SupportsManagedIdentity), | ||
| nameof(Config.SupportsSystemAssignedManagedIdentity), | ||
| nameof(Config.HasPasswordConnectionString))] | ||
| nameof(Config.HasAzureSqlConnectionString))] | ||
| public static void SystemAssigned_ManagedIdentityTest() | ||
| { | ||
| string[] removeKeys = { "Authentication", "User ID", "Password", "UID", "PWD" }; | ||
| string connStr = RemoveKeysInConnStr(Config.PasswordConnectionString, removeKeys) + | ||
| $"Authentication=Active Directory Managed Identity;"; | ||
| string connStr = Config.AzureSqlConnString | ||
| .AddManagedIdentityAuthenticationToConnString(); | ||
|
|
||
| ConnectAndDisconnect(connStr); | ||
| } | ||
|
|
||
| [ConditionalFact( | ||
| typeof(Config), | ||
| nameof(Config.OnAdoPool), | ||
| nameof(Config.HasPasswordConnectionString), | ||
| nameof(Config.HasAzureSqlConnectionString), | ||
| nameof(Config.HasUserManagedIdentityClientId))] | ||
| public static void UserAssigned_ManagedIdentityTest() | ||
| { | ||
| string[] removeKeys = { "Authentication", "User ID", "Password", "UID", "PWD" }; | ||
| string connStr = RemoveKeysInConnStr(Config.PasswordConnectionString, removeKeys) + | ||
| $"Authentication=Active Directory Managed Identity; User Id={Config.UserManagedIdentityClientId};"; | ||
| string connStr = Config.AzureSqlConnString | ||
| .AddManagedIdentityAuthenticationToConnString() | ||
| .AddUserToConnString(Config.UserManagedIdentityClientId); | ||
|
|
||
| ConnectAndDisconnect(connStr); | ||
| } | ||
|
|
||
|
|
@@ -145,16 +153,14 @@ public static void UserAssigned_ManagedIdentityTest() | |
| nameof(Config.IsAzureSqlServer))] | ||
| public static void Azure_SystemManagedIdentityTest() | ||
| { | ||
| string[] removeKeys = { "Authentication", "User ID", "Password", "UID", "PWD", "Trusted_Connection", "Integrated Security" }; | ||
| string connectionString = RemoveKeysInConnStr(Config.TcpConnectionString, removeKeys) | ||
| + $"Authentication=Active Directory Managed Identity;"; | ||
| string connectionString = Config.TcpConnectionString | ||
| .RemoveAuthAndCredsProperties() | ||
| .AddManagedIdentityAuthenticationToConnString(); | ||
|
|
||
| using (SqlConnection conn = new SqlConnection(connectionString)) | ||
| { | ||
| conn.Open(); | ||
| using SqlConnection conn = new(connectionString); | ||
| conn.Open(); | ||
|
|
||
| Assert.Equal(System.Data.ConnectionState.Open, conn.State); | ||
| } | ||
| Assert.Equal(System.Data.ConnectionState.Open, conn.State); | ||
| } | ||
|
|
||
| [ConditionalFact( | ||
|
|
@@ -166,16 +172,15 @@ public static void Azure_SystemManagedIdentityTest() | |
| nameof(Config.IsAzureSqlServer))] | ||
| public static void Azure_UserManagedIdentityTest() | ||
| { | ||
| string[] removeKeys = { "Authentication", "User ID", "Password", "UID", "PWD", "Trusted_Connection", "Integrated Security" }; | ||
| string connectionString = RemoveKeysInConnStr(Config.TcpConnectionString, removeKeys) | ||
| + $"Authentication=Active Directory Managed Identity; User Id={Config.UserManagedIdentityClientId}"; | ||
| string connectionString = Config.TcpConnectionString | ||
| .RemoveAuthAndCredsProperties() | ||
| .AddManagedIdentityAuthenticationToConnString() | ||
| .AddUserToConnString(Config.UserManagedIdentityClientId); | ||
|
|
||
| using (SqlConnection conn = new SqlConnection(connectionString)) | ||
| { | ||
| conn.Open(); | ||
| using SqlConnection conn = new(connectionString); | ||
| conn.Open(); | ||
|
|
||
| Assert.Equal(System.Data.ConnectionState.Open, conn.State); | ||
| } | ||
| Assert.Equal(System.Data.ConnectionState.Open, conn.State); | ||
| } | ||
|
|
||
| // The helpers below were copied verbatim from AADConnectionTest.cs and ManualTests | ||
|
|
@@ -203,36 +208,6 @@ private static void ConnectAndDisconnect( | |
|
|
||
| #region Helpers from ManualTests DataTestUtility.cs | ||
|
|
||
| public static string RemoveKeysInConnStr(string connStr, string[] keysToRemove) | ||
| { | ||
| // tokenize connection string and remove input keys. | ||
| string res = ""; | ||
| if (connStr != null && keysToRemove != null) | ||
| { | ||
| string[] keys = connStr.Split(';'); | ||
| foreach (var key in keys) | ||
| { | ||
| if (!string.IsNullOrEmpty(key.Trim())) | ||
| { | ||
| bool removeKey = false; | ||
| foreach (var keyToRemove in keysToRemove) | ||
| { | ||
| if (key.Trim().ToLower().StartsWith(keyToRemove.Trim().ToLower(), StringComparison.Ordinal)) | ||
| { | ||
| removeKey = true; | ||
| break; | ||
| } | ||
| } | ||
| if (!removeKey) | ||
| { | ||
| res += key + ";"; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return res; | ||
| } | ||
|
|
||
| public static string? FetchKeyInConnStr(string connStr, string[] keys) | ||
| { | ||
| // tokenize connection string and find matching key | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit concerned with making this change.
The PR pipeline uses two different test runs, one for localhost, one for azure. The differentiation is made by running it once with an azure connection string for TCPConnectionString/NPConnectionString and then using a localhost connection string. This allows us to run the same set of tests on both environments, since the tests just specify if it can't run on Azure (or I suppose only run on Azure) based on the TCP/NP connection string that was provided.
Changing this "AADPasswordConnectionString" to "AzureSqlConnectionString" and changing the comments for TCP and NP mixes up the ideas. The new guidance suggests that tests are either azure-specific or localhost-specific. But, aside from the handful being changed in this PR, they are not azure/localhost specific. And, worse, in order to enable azure/localhost specific tests, we would need to duplicate all the existing tests that use TCP/NP.
eg, we'd have to change from
to
That seems like a really bad idea to me.
I've been percolating on a better way for us to handle multiple connection strings for our test scenarios. I'd really like a bit of runway to put together a prototype for how it could be used to improve our manual tests.
But anyhow, my general feedback for this would be ... maybe we shouldn't change the name and guidance on these connection strings right now. Maybe we should just make sure that we eliminate the AAD password auth from the tests, but not go further than that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 can we just remove the 'AADPasswordConnectionString'? why do we need a replacement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, I think that's a fair change.