Using SQL Always Encrypted with Entity Framework

I created some sample code to demonstrate how to use SQL Always Encrypted with Entity Framework. The sample assumed the SQL Always Encrypted is configured with Azure Key Vault, and a Service Principal has permissions to access the keys in the Key Vault.

The key part of the code is as follows (it is for .NET Core. The code for .NET Framework is quite similar). Not like the sample in the above linked document, the AAD authentication is implemented with MSAL rather than ADAL.

public void ConfigureServices(IServiceCollection services)
 {
     spClientId = Configuration.GetValue("spClientId");
     spClientSecret = Configuration.GetValue("spClientSecret");
     SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider = new SqlColumnEncryptionAzureKeyVaultProvider(AADAuthenticationCallback); 
     SqlConnection.RegisterColumnEncryptionKeyStoreProviders(new Dictionary<string, SqlColumnEncryptionKeyStoreProvider> 
     {
         { SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider }
     }); 
     services.AddDbContext<TodoContext>(
         options => options.UseSqlServer(Configuration.GetConnectionString("TodoDBConnection"))
     );
     
     ...
 }

 private static async Task AADAuthenticationCallback(string authority, string resource, string scope)
 {
     var clientApp = ConfidentialClientApplicationBuilder
         .Create(spClientId)
         .WithClientSecret(spClientSecret)
         .WithAuthority(authority)
         .Build();
     var scopes = new[] { resource + "/.default" };
     var authResult = await clientApp.AcquireTokenForClient(scopes).ExecuteAsync();
     if (authResult == null)
     {
         throw new Exception("Failed to acquire the access token.");
     }

     return authResult.AccessToken;
 }

One thing to note is the package of the AzureKeyVaultProvider for Always Encrypted. For EF Core, the package is Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider. But for EF6, Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider should be used. That is because Microsoft.Data.SqlClient is not compatible with EF6.