Always Encrypted Azure Key Vault Support (#934)

Add support for running queries that require a decryption key from Azure Key Vault when using Always Encrypted.
This commit is contained in:
Jeff Trimmer
2020-03-19 12:48:05 -07:00
committed by GitHub
parent 9ea076e51d
commit 6920c34570
5 changed files with 78 additions and 2 deletions

View File

@@ -9,6 +9,7 @@ using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using Microsoft.Data.SqlClient;
using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
using System.Globalization;
using System.Linq;
using System.Threading;
@@ -105,6 +106,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
}
}
static ConnectionService()
{
SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider = new SqlColumnEncryptionAzureKeyVaultProvider(AzureActiveDirectoryAuthenticationCallback);
SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders: new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>(capacity: 1, comparer: StringComparer.OrdinalIgnoreCase)
{
{ SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, sqlColumnEncryptionAzureKeyVaultProvider }
});
}
/// <summary>
/// Default constructor should be private since it's a singleton class, but we need a constructor
@@ -117,6 +127,21 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
this.LockedDatabaseManager.ConnectionService = this;
}
public static async Task<string> AzureActiveDirectoryAuthenticationCallback(string authority, string resource, string scope)
{
RequestSecurityTokenParams message = new RequestSecurityTokenParams()
{
Authority = authority,
Provider = "Azure",
Resource = resource,
Scope = scope
};
RequestSecurityTokenResponse response = await Instance.ServiceHost.SendRequest(SecurityTokenRequest.Type, message, true);
return response.Token;
}
/// <summary>
/// Returns a connection queue for given type
/// </summary>