Partilhar via


Conectar-se ao SQL do Azure com autenticação Microsoft Entra e SqlClient

Aplica-se a: .NET Framework .NET .NET Standard

Descarregar ADO.NET

Este artigo descreve como se conectar a fontes de dados SQL do Azure usando a autenticação do Microsoft Entra de um aplicativo .NET com SqlClient.

Observação

Embora o Microsoft Entra ID seja o novo nome para o Azure Ative Directory (Azure AD), para evitar a interrupção de ambientes existentes, o Azure AD ainda permanece em alguns elementos codificados, como campos de interface do usuário, provedores de conexão, códigos de erro e cmdlets. Neste artigo, os dois nomes são intercambiáveis.

Visão geral

A autenticação do Microsoft Entra usa identidades na ID do Microsoft Entra para acessar fontes de dados como o Banco de Dados SQL do Azure, a Instância Gerenciada SQL do Azure e o Azure Synapse Analytics. O namespace Microsoft.Data.SqlClient permite que os aplicativos cliente especifiquem credenciais do Microsoft Entra em diferentes modos de autenticação quando estão se conectando ao Banco de Dados SQL do Azure e à Instância Gerenciada SQL do Azure. Para usar a autenticação do Microsoft Entra com o Azure SQL, você deve configurar e gerenciar a autenticação do Microsoft Entra com o Azure SQL.

Quando você define a Authentication propriedade de conexão na cadeia de conexão, o cliente pode escolher um modo de autenticação preferencial do Microsoft Entra de acordo com o valor fornecido:

  • A versão mais antiga do Microsoft.Data.SqlClient oferece suporte Active Directory Password para .NET Framework, .NET Core e .NET Standard. Ele também suporta Active Directory Integrated autenticação e Active Directory Interactive autenticação para .NET Framework.

  • A partir do Microsoft.Data.SqlClient 2.0.0, o suporte para autenticações Active Directory Integrated e Active Directory Interactive é estendido ao .NET Framework, .NET Core e .NET Standard.

    Um novo Active Directory Service Principal modo de autenticação também é adicionado no SqlClient 2.0.0. Ele usa o ID do cliente e o segredo de uma identidade principal de serviço para realizar a autenticação.

  • Mais modos de autenticação são adicionados em Microsoft.Data.SqlClient 2.1.0, incluindo Active Directory Device Code Flow e Active Directory Managed Identity (também conhecido como Active Directory MSI). Esses novos modos permitem que o aplicativo adquira um token de acesso para se conectar ao servidor.

Para obter informações sobre a autenticação do Microsoft Entra além do que as seções a seguir descrevem, consulte Usar a autenticação do Microsoft Entra.

Definindo a autenticação do Microsoft Entra

Quando o aplicativo está se conectando a fontes de dados SQL do Azure usando a autenticação do Microsoft Entra, ele precisa fornecer um modo de autenticação válido. A tabela a seguir lista os modos de autenticação suportados. A aplicação especifica um modo usando a propriedade de ligação Authentication na string de conexão.

Valor Descrição Versão Microsoft.Data.SqlClient
Palavra-passe do Ative Directory Autenticar com um nome de usuário e senha de identidade do Microsoft Entra 1.0+
Active Directory Integrado Autentique-se com uma identidade do Microsoft Entra usando a Autenticação Integrada do Windows (IWA) 2.0.0+1
Active Directory Interativo Autenticar com uma identidade do Microsoft Entra usando autenticação interativa 2.0.0+1
Entidade de Serviço do Active Directory Autenticar com uma entidade de serviço Microsoft Entra, usando o seu ID de cliente e chave secreta 2.0.0+
Fluxo de código de dispositivo do Ative Directory Autenticar com uma identidade do Microsoft Entra usando o modo Device Code Flow 2.1.0+
Identidade Gerenciada do Ative Directory,
Active Directory MSI
Autenticar usando uma identidade gerenciada atribuída pelo sistema Microsoft Entra ou pelo usuário 2.1.0+
Padrão do Ative Directory Autentique-se com uma identidade do Microsoft Entra usando mecanismos sem senha e não interativos, incluindo identidades gerenciadas, Visual Studio Code, Visual Studio, CLI do Azure, etc. 3.0.0+
Identidade da carga de trabalho do Ative Directory Autentique-se com uma identidade do Microsoft Entra usando uma Identidade Gerenciada Atribuída ao Usuário federado para se conectar ao Banco de Dados SQL a partir de ambientes de cliente do Azure habilitados para Identidade de Carga de Trabalho. 5.2.0+

1 Antes de Microsoft.Data.SqlClient 2.0.0, Active Directory Integratede Active Directory Interactive os modos de autenticação são suportados apenas no .NET Framework.

Usando a autenticação de senha

Active Directory Password o modo de autenticação dá suporte à autenticação em fontes de dados do Azure com a ID do Microsoft Entra para usuários nativos ou federados do Microsoft Entra. Quando você estiver usando esse modo, as credenciais do usuário devem ser fornecidas na cadeia de conexão. O exemplo a seguir mostra como usar Active Directory Password a autenticação.

// Use your own server, database, user ID, and password.
string ConnectionString = @"Server=demo.database.windows.net;"
   + "Authentication=Active Directory Password; Encrypt=True; Database=testdb;"
   + "User Id=user@domain.com; Password=<password>";

using (SqlConnection conn = new SqlConnection(ConnectionString)) {
    conn.Open();
}

Usando autenticação integrada

Para usar Active Directory Integrated o modo de autenticação, você deve ter uma instância do Ative Directory local que esteja associada à ID do Microsoft Entra na nuvem. Você pode federar usando os Serviços de Federação do Ative Directory (AD FS), por exemplo.

Quando você está conectado a uma máquina associada a um domínio, você pode acessar fontes de dados SQL do Azure sem ser solicitado a fornecer credenciais com esse modo. Não é possível especificar nome de usuário e senha na cadeia de conexão para aplicativos .NET Framework. O nome de usuário é opcional na cadeia de conexão para aplicativos .NET Core e .NET Standard. Não é possível definir a Credential propriedade de SqlConnection neste modo.

O trecho de código a seguir é um exemplo de quando Active Directory Integrated a autenticação está em uso.

// Use your own server and database.
string ConnectionString1 = @"Server=demo.database.windows.net;"
  + "Authentication=Active Directory Integrated; Encrypt=True; Database=testdb";

using (SqlConnection conn = new SqlConnection(ConnectionString1)) {
    conn.Open();
}

// User ID is optional for .NET Core and .NET Standard.
string ConnectionString2 = @"Server=demo.database.windows.net;"
  + "Authentication=Active Directory Integrated; Encrypt=True; Database=testdb;"
  + "User Id=user@domain.com";

using (SqlConnection conn = new SqlConnection(ConnectionString2)) {
    conn.Open();
}

Usando autenticação interativa

Active Directory Interactive a autenticação dá suporte à tecnologia de autenticação multifator para se conectar a fontes de dados SQL do Azure. Se você fornecer esse modo de autenticação na cadeia de conexão, uma tela de autenticação do Azure será exibida e solicitará que o usuário insira credenciais válidas. Não é possível especificar a senha na cadeia de conexão.

Não é possível definir a Credential propriedade de SqlConnection neste modo. Com Microsoft.Data.SqlClient 2.0.0 e posterior, o nome de usuário é permitido na cadeia de conexão quando você está no modo interativo.

O exemplo a seguir mostra como usar Active Directory Interactive a autenticação.

// Use your own server, database, and user ID.
// User ID is optional.
string ConnectionString1 = @"Server=demo.database.windows.net;"
   + "Authentication=Active Directory Interactive; Encrypt=True;" 
   + "Database=testdb; User Id=user@domain.com";

using (SqlConnection conn = new SqlConnection(ConnectionString1)) {
    conn.Open();
}

// User ID is not provided.
string ConnectionString2 = @"Server=demo.database.windows.net;"
   + "Authentication=Active Directory Interactive; Encrypt=True;"
   + "Database=testdb";

using (SqlConnection conn = new SqlConnection(ConnectionString2)) {
    conn.Open();
}

Usando a autenticação da entidade de serviço

No Active Directory Service Principal modo de autenticação, o aplicativo cliente pode se conectar a fontes de dados SQL do Azure fornecendo a ID do cliente e o segredo de uma identidade de entidade de serviço. A autenticação do principal de serviço envolve:

  1. Configurar um registo de aplicação com um segredo.
  2. Conceder permissões ao aplicativo na instância do Banco de Dados SQL do Azure.
  3. Conectando-se com a credencial correta.

O exemplo a seguir mostra como usar Active Directory Service Principal a autenticação.

// Use your own server, database, app ID, and secret.
string ConnectionString = @"Server=demo.database.windows.net;"
  + "Authentication=Active Directory Service Principal; Encrypt=True;"
  + "Database=testdb; User Id=AppId; Password=<password>";

using (SqlConnection conn = new SqlConnection(ConnectionString)) {
    conn.Open();
}

Usando a autenticação de fluxo de código de dispositivo

Com a Biblioteca de Autenticação da Microsoft para .NET (MSAL.NET), Active Directory Device Code Flow a autenticação permite que o aplicativo cliente se conecte a fontes de dados SQL do Azure a partir de dispositivos e sistemas operacionais que não têm um navegador da Web interativo. A autenticação interativa é realizada em outro dispositivo. Para obter mais informações sobre a autenticação de fluxo de código de dispositivo, consulte OAuth 2.0 Device Code Flow.

Quando esse modo está em uso, não é possível definir a Credential propriedade de SqlConnection. Além disso, o nome de usuário e a senha não devem ser especificados na cadeia de conexão.

O trecho de código a seguir é um exemplo de uso Active Directory Device Code Flow da autenticação.

Observação

O tempo limite para Active Directory Device Code Flow é padrão na configuração da Connect Timeout conexão. Certifique-se de especificar um Connect Timeout que forneça tempo suficiente para passar pelo processo de autenticação do fluxo de código do dispositivo.

// Use your own server and database and increase Connect Timeout as needed for
// device code flow.
string ConnectionString = @"Server=demo.database.windows.net;"
  + "Authentication=Active Directory Device Code Flow; Encrypt=True;"
  + "Database=testdb; Connect Timeout=180;";

using (SqlConnection conn = new SqlConnection(ConnectionString)) {
    conn.Open();
}

Usando a autenticação de identidade gerenciada

A autenticação com identidades gerenciadas para recursos do Azure é o método de autenticação recomendado para acesso programático ao SQL. Um aplicativo cliente pode usar a identidade gerenciada atribuída pelo sistema ou pelo usuário de um recurso para autenticar no SQL com a ID do Microsoft Entra, fornecendo a identidade e usando-a para obter tokens de acesso. Esse método elimina a necessidade de gerenciar credenciais e segredos e pode simplificar o gerenciamento de acesso.

Existem dois tipos de identidades gerenciadas:

  • A identidade gerenciada atribuída ao sistema é criada como parte de um recurso do Azure (como sua instância gerenciada SQL ou o servidor lógico) e compartilha o ciclo de vida desse recurso. As identidades atribuídas pelo sistema só podem ser associadas a um único recurso do Azure.
  • A identidade gerenciada atribuída pelo usuário é criada como um recurso autônomo do Azure. Ele pode ser atribuído a uma ou mais instâncias de um serviço do Azure.

Para obter mais informações sobre identidades gerenciadas, consulte Sobre identidades gerenciadas para recursos do Azure.

Desde o Microsoft.Data.SqlClient 2.1.0, o driver dá suporte à autenticação no Banco de Dados SQL do Azure, no Azure Synapse Analytics e na Instância Gerenciada SQL do Azure adquirindo tokens de acesso por meio da identidade gerenciada. Para usar esta autenticação, especifique ou Active Directory Managed Identity ou Active Directory MSI na cadeia de conexão, e nenhuma senha é necessária. Também não é possível definir a Credential propriedade de SqlConnection neste modo.

Para uma identidade gerenciada atribuída pelo usuário, a ID do cliente da identidade gerenciada deve ser fornecida ao usar Microsoft.Data.SqlClient v3.0 ou mais recente. Se estiver usando Microsoft.Data.SqlClient v2.1, a id do objeto da identidade gerenciada deverá ser fornecida.

O exemplo a seguir mostra como usar Active Directory Managed Identity a autenticação com uma identidade gerenciada atribuída ao sistema.

// For system-assigned managed identity
// Use your own values for Server and Database.
string ConnectionString1 = @"Server=demo.database.windows.net;"
  + "Authentication=Active Directory Managed Identity; Encrypt=True;"
  + "Database=testdb";

using (SqlConnection conn = new SqlConnection(ConnectionString1)) {
    conn.Open();
}

string ConnectionString2 = @"Server=demo.database.windows.net;"
  + "Authentication=Active Directory MSI; Encrypt=True; Database=testdb";

using (SqlConnection conn = new SqlConnection(ConnectionString2)) {
    conn.Open();
}

O exemplo a seguir demonstra Active Directory Managed Identity a autenticação com uma identidade gerenciada atribuída pelo usuário com Microsoft.Data.SqlClient v3.0 em diante.

// For user-assigned managed identity
// Use your own values for Server, Database, and User Id.

// With Microsoft.Data.SqlClient v3.0+
string ConnectionString1 = @"Server=demo.database.windows.net;"
  + "Authentication=Active Directory Managed Identity; Encrypt=True;"
  + "User Id=ClientIdOfManagedIdentity; Database=testdb";

using (SqlConnection conn = new SqlConnection(ConnectionString1)) {
    conn.Open();
}

// With Microsoft.Data.SqlClient v3.0+
string ConnectionString2 = @"Server=demo.database.windows.net;"
  + "Authentication=Active Directory MSI; Encrypt=True;"
  + "User Id=ClientIdOfManagedIdentity; Database=testdb";

using (SqlConnection conn = new SqlConnection(ConnectionString2)) {
    conn.Open();
}

O exemplo a seguir demonstra Active Directory Managed Identity a autenticação com uma identidade gerenciada atribuída pelo usuário com Microsoft.Data.SqlClient v2.1.

// For user-assigned managed identity
// Use your own values for Server, Database, and User Id.

// With Microsoft.Data.SqlClient v2.1
string ConnectionString1 = @"Server=demo.database.windows.net;"
  + "Authentication=Active Directory Managed Identity; Encrypt=True;"
  + "User Id=ObjectIdOfManagedIdentity; Database=testdb";

using (SqlConnection conn = new SqlConnection(ConnectionString1)) {
    conn.Open();
}

// With Microsoft.Data.SqlClient v2.1
string ConnectionString2 = @"Server=demo.database.windows.net;"
  + "Authentication=Active Directory MSI; Encrypt=True;"
  + "User Id=ObjectIdOfManagedIdentity; Database=testdb";

using (SqlConnection conn = new SqlConnection(ConnectionString2)) {
    conn.Open();
}

Usando a autenticação padrão

Disponível a partir da versão 3.0, este modo de autenticação amplia as possibilidades de autenticação do usuário. Esse modo estende as soluções de logon para o ambiente do cliente, Visual Studio Code, Visual Studio, Azure CLI etc.

Com esse modo de autenticação, o driver adquire um token passando "DefaultAzureCredential" da biblioteca de Identidade do Azure para adquirir um token de acesso. Este modo tenta usar um conjunto de tipos de credenciais para adquirir um token de acesso sequencialmente. Dependendo da versão da biblioteca de Identidade do Azure usada, o conjunto de credenciais varia. As diferenças específicas da versão são anotadas na lista. Para o comportamento específico da versão do Azure Identity, consulte os documentos da API Azure.Identity.

Importante

O Ative Directory Default é uma opção conveniente para simplificar as diferenças de cadeia de conexão entre diferentes ambientes. No entanto, ele pode vir com impactos no desempenho porque precisa procurar informações de autenticação em vários lugares. Se observar velocidades de conexão lentas usando o Padrão do Active Directory, opte por uma opção de autenticação diferente que vise especificamente o método de autenticação em uso no seu ambiente. "Active Directory Padrão" não é recomendado para ambientes que têm tempos de resposta de níveis de serviço estritos.

  • CredencialDoAmbiente
    • Permite a autenticação com o Microsoft Entra ID usando cliente e segredo, ou nome de usuário e senha, detalhes configurados nas seguintes variáveis de ambiente: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_CLIENT_CERTIFICATE_PATH, AZURE_USERNAME, AZURE_PASSWORD (Mais detalhes)
  • WorkloadIdentityCredential
    • Habilita a autenticação de Identidade de Carga de Trabalho do Microsoft Entra no Kubernetes e em outros hosts que suportam identidade de carga de trabalho. Para obter mais informações, consulte ID de Carga de Trabalho do Microsoft Entra. Disponível a partir do Azure Identity versão 1.10 e Microsoft.Data.SqlClient 5.1.4.
  • ManagedIdentityCredential
    • Tenta autenticação com o Microsoft Entra ID usando uma identidade gerenciada atribuída ao ambiente de implantação. "Client Id" de "User Assigned Managed Identity" é lido a partir da propriedade de conexão "User Id".
  • SharedTokenCacheCredential (Credencial de Cache de Token Compartilhado)
    • Autentica usando tokens no cache local compartilhado entre aplicativos da Microsoft.
  • VisualStudioCredential
    • Habilita a autenticação com o Microsoft Entra ID usando dados do Visual Studio
  • VisualStudioCodeCredential
    • Habilita a autenticação com o Microsoft Entra ID usando dados do Visual Studio Code.
  • AzurePowerShellCredential
    • Habilita a autenticação com o Microsoft Entra ID usando o Azure PowerShell. Disponível a partir do Azure Identity versão 1.6 e Microsoft.Data.SqlClient 5.0.
  • AzureCliCredential
    • Habilita a autenticação com o Microsoft Entra ID usando a CLI do Azure para obter um token de acesso.
  • AzureDeveloperCliCredential
    • Habilita a autenticação para o Microsoft Entra ID usando a CLI do Desenvolvedor do Azure para obter um token de acesso. Disponível a partir do Azure Identity versão 1.10 e Microsoft.Data.SqlClient 5.1.4.

Observação

InteractiveBrowserCredential está desabilitado na implementação de driver do Ative Directory Default, e o Ative Directory Interactive é a única opção disponível para adquirir um token usando a autenticação MFA/Interactive.

Outras opções de personalização não estão disponíveis no momento.

O exemplo a seguir mostra como usar a autenticação padrão do Ative Directory .

// Use your own server, database
string ConnectionString = @"Server=demo.database.windows.net;"
  + "Authentication=Active Directory Default; Encrypt=True; Database=testdb;";

using (SqlConnection conn = new SqlConnection(ConnectionString)) {
    conn.Open();
}

Usando a autenticação de identidade de carga de trabalho

Disponível a partir da versão 5.2, como nas identidades gerenciadas, o modo de autenticação de User ID usa o valor do parâmetro na cadeia de conexão para sua ID de cliente, se especificado. Mas, ao contrário da identidade gerenciada, WorkloadIdentityCredentialOptions padroniza seu valor a partir de variáveis de ambiente: AZURE_TENANT_ID, AZURE_CLIENT_ID e AZURE_FEDERATED_TOKEN_FILE. No entanto, somente a ID do cliente pode ser substituída pela cadeia de conexão.

O exemplo a seguir demonstra Active Directory Workload Identity a autenticação com uma identidade gerenciada atribuída pelo usuário com Microsoft.Data.SqlClient v5.2 em diante.

// Use your own values for Server, Database, and User Id.
// With Microsoft.Data.SqlClient v5.2+
string ConnectionString = @"Server=demo.database.windows.net;"
  + "Authentication=Active Directory Workload Identity; Encrypt=True;"
  + "User Id=ClientIdOfManagedIdentity; Database=testdb";

using (SqlConnection conn = new SqlConnection(ConnectionString)) {
    conn.Open();
}

Personalizando a autenticação do Microsoft Entra

Além de usar a autenticação Microsoft Entra incorporada no driver, Microsoft.Data.SqlClient 2.1.0 e posterior fornecem aos aplicativos a opção de personalizar a autenticação do Microsoft Entra. A personalização é baseada na ActiveDirectoryAuthenticationProvider classe, que é derivada da SqlAuthenticationProvider classe abstrata.

Durante a autenticação do Microsoft Entra, o aplicativo cliente pode definir sua própria ActiveDirectoryAuthenticationProvider classe:

  • Usando um método de retorno de chamada personalizado.
  • Passando um identificador de cliente da aplicação para a biblioteca MSAL através do driver SqlClient para obter tokens de acesso.

O exemplo a seguir exibe como usar um retorno de chamada personalizado quando Active Directory Device Code Flow a autenticação está em uso.

using System;
using System.Threading.Tasks;
using Microsoft.Identity.Client;
using Microsoft.Data.SqlClient;

namespace CustomDeviceCodeFlowAuthProviderExample
{
    public class Program
    {
        public static void Main()
        {
            SqlAuthenticationProvider authProvider = new ActiveDirectoryAuthenticationProvider(CustomDeviceFlowCallback);
            SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow, authProvider);
            using (SqlConnection sqlConnection = new SqlConnection("Server=<myserver>.database.windows.net;Authentication=Active Directory Device Code Flow;Database=<db>;"))
            {
                sqlConnection.Open();
                Console.WriteLine("Connected successfully!");
            }
        }

        private static Task CustomDeviceFlowCallback(DeviceCodeResult result)
        {
            // Provide custom logic to process result information and read device code.
            Console.WriteLine(result.Message);
            return Task.FromResult(0);
        }
    }
}

Com uma classe personalizada ActiveDirectoryAuthenticationProvider , um ID de cliente de aplicativo definido pelo usuário pode ser passado para SqlClient quando um modo de autenticação Microsoft Entra suportado está em uso. Os modos de autenticação do Microsoft Entra suportados incluem Active Directory Password, Active Directory Integrated, Active Directory Interactive, Active Directory Service Principale Active Directory Device Code Flow.

O ID do cliente do aplicativo também é configurável via SqlAuthenticationProviderConfigurationSection ou SqlClientAuthenticationProviderConfigurationSection. A propriedade applicationClientId configuration se aplica ao .NET Framework 4.6+ e ao .NET Core 2.1+.

O trecho de código a seguir é um exemplo de uso de uma classe personalizada ActiveDirectoryAuthenticationProvider com uma ID de cliente de aplicativo definida pelo usuário quando Active Directory Interactive a autenticação está em uso.

using System;
using Microsoft.Data.SqlClient;

namespace CustomAppIdAuthProviderExample
{
    public class Program
    {
        public static void Main()
        {
            // Supported for all authentication modes supported by ActiveDirectoryAuthenticationProvider
            ActiveDirectoryAuthenticationProvider provider = new ActiveDirectoryAuthenticationProvider("<application_client_id>");
            if (provider.IsSupported(SqlAuthenticationMethod.ActiveDirectoryInteractive))
            {
                SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryInteractive, provider);
            }
            
            using (SqlConnection sqlConnection = new SqlConnection("Server=<myserver>.database.windows.net;Authentication=Active Directory Interactive;Database=<db>;"))
            {
                sqlConnection.Open();
                Console.WriteLine("Connected successfully!");
            }
        }
    }
}

O exemplo a seguir mostra como definir um ID de cliente de aplicativo por meio de uma seção de configuração.

<configuration>
  <configSections>
    <section name="SqlClientAuthenticationProviders"
             type="Microsoft.Data.SqlClient.SqlClientAuthenticationProviderConfigurationSection, Microsoft.Data.SqlClient" />
  </configSections>
  <SqlClientAuthenticationProviders applicationClientId ="<GUID>" />
</configuration>

<!--or-->

<configuration>
  <configSections>
    <section name="SqlAuthenticationProviders"
             type="Microsoft.Data.SqlClient.SqlAuthenticationProviderConfigurationSection, Microsoft.Data.SqlClient" />
  </configSections>
  <SqlAuthenticationProviders applicationClientId ="<GUID>" />
</configuration>

Usando AccessTokenCallback

Disponível na versão 5.2 em diante, há uma nova propriedade AccessTokenCallback em SqlConnection. Use a AccessTokenCallback propriedade para definir uma função personalizada que retorna um token de acesso dados os parâmetros de entrada. Usar o retorno de chamada é melhor do que usar a propriedade AccessToken porque permite que o token de acesso seja atualizado dentro de um pool de conexões. Ao usar a AccessToken propriedade, o token não pode ser atualizado depois de abrir a conexão. Também não é fornecida uma data de validade associada à propriedade. Quando o token expira, novas solicitações de conexão falham com um erro de autenticação do servidor e os pools que o usam devem ser limpos manualmente.

Importante

Um AccessTokenCallback deve retornar tokens de acesso do mesmo contexto de segurança para os mesmos parâmetros de entrada. Se o contexto de segurança for diferente, uma conexão agrupada com o contexto de segurança errado pode ser retornada para uma solicitação de conexão.

Observação

AccessTokenCallback faz parte da chave usada para identificar pools de conexões. Evite criar um callback de função para cada criação de um SqlConnection, pois isso resulta sempre em um novo pool. Faça referência à mesma instância de uma função para as conexões que desejas considerar para agrupamento. A chave do pool de conexões inclui parâmetros passados para a função de retorno, a fim de particionar os pools de conexões de forma apropriada.

O trecho de código a seguir é um exemplo de uso da AccessTokenCallback propriedade em Microsoft.Data.SqlClient v5.2 em diante.

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core;
using Azure.Identity;
using Microsoft.Data.SqlClient;

class Program
{
    static void Main()
    {
        OpenSqlConnection();
        Console.ReadLine();
    }

    const string defaultScopeSuffix = "/.default";

    // Reuse credential objects to take advantage of underlying token caches.
    private static ConcurrentDictionary<string, DefaultAzureCredential> credentials = new ConcurrentDictionary<string, DefaultAzureCredential>();

    // Use a shared callback function for connections that should be in the same connection pool.
    private static Func<SqlAuthenticationParameters, CancellationToken, Task<SqlAuthenticationToken>> myAccessTokenCallback =
        async (authParams, cancellationToken) =>
        {
            string scope = authParams.Resource.EndsWith(defaultScopeSuffix)
                ? authParams.Resource
                : $"{authParams.Resource}{defaultScopeSuffix}";

            DefaultAzureCredentialOptions options = new DefaultAzureCredentialOptions();
            options.ManagedIdentityClientId = authParams.UserId;

            // Reuse the same credential object if we are using the same MI Client Id.
            AccessToken token = await credentials.GetOrAdd(authParams.UserId, new DefaultAzureCredential(options)).GetTokenAsync(
                new TokenRequestContext(new string[] { scope }),
                cancellationToken);

            return new SqlAuthenticationToken(token.Token, token.ExpiresOn);
        };

    private static void OpenSqlConnection()
    {
        // (Optional) Pass a User-Assigned Managed Identity Client ID.
        // This will ensure different MI Client IDs are in different connection pools.
        string connectionString = "Server=myServer.database.windows.net;Encrypt=Mandatory;UserId=<ManagedIdentitityClientId>;";

        using (SqlConnection connection = new SqlConnection(connectionString)
        {
            // The callback function is part of the connection pool key. Using a static callback function
            // ensures connections will not create a new pool per connection just for the callback.
            AccessTokenCallback = myAccessTokenCallback
        })
        {
            connection.Open();
            Console.WriteLine("ServerVersion: {0}", connection.ServerVersion);
            Console.WriteLine("State: {0}", connection.State);
        }
    }
}

Suporte para um provedor de autenticação SQL personalizado

Dada mais flexibilidade, o aplicativo cliente também pode usar seu próprio provedor para autenticação do Microsoft Entra em vez de usar a ActiveDirectoryAuthenticationProvider classe. O provedor de autenticação personalizado precisa ser uma subclasse de SqlAuthenticationProvider com métodos substituídos. Em seguida, ele deve registrar o provedor personalizado, substituindo um ou mais dos métodos de autenticação existentes Active Directory* .

Importante

Um provedor de autenticação deve retornar tokens de acesso do mesmo contexto de segurança para os mesmos parâmetros de entrada. Se o contexto de segurança for diferente, uma conexão agrupada com o contexto de segurança errado pode ser retornada para uma solicitação de conexão.

O exemplo a seguir mostra como usar um novo provedor de autenticação para a autenticação de Active Directory Device Code Flow.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Data.SqlClient;
using Microsoft.Identity.Client;

namespace CustomDeviceCodeFlowAuthProviderExample
{
    /// <summary>
    /// Example demonstrating creating a custom device code flow authentication provider and attaching it to the driver.
    /// This is helpful for applications that wish to override the Callback for the Device Code Result implemented by the SqlClient driver.
    /// </summary>
    public class CustomDeviceCodeFlowAzureAuthenticationProvider : SqlAuthenticationProvider
    {
        private const string ClientId = "my-client-id";
        private const string ClientName = "My Application Name";
        private const string DefaultScopeSuffix = "/.default";

        // Maintain a copy of the PublicClientApplication object to cache the underlying access tokens it provides
        private static IPublicClientApplication pcApplication;

        public override async Task<SqlAuthenticationToken> AcquireTokenAsync(SqlAuthenticationParameters parameters)
        {
            string[] scopes = [ parameters.Resource.EndsWith(DefaultScopeSuffix) ? parameters.Resource : parameters.Resource + DefaultScopeSuffix ];

            IPublicClientApplication app = pcApplication;
            if (app == null)
            {
                pcApplication = app = PublicClientApplicationBuilder.Create(ClientId)
                    .WithAuthority(parameters.Authority)
                    .WithClientName(ClientName)
                    .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
                    .Build();
            }

            AuthenticationResult result;
            using CancellationTokenSource connectionTimeoutCancellation = new CancellationTokenSource(TimeSpan.FromSeconds(parameters.ConnectionTimeout));

            try
            {
                IEnumerable<IAccount> accounts = await app.GetAccountsAsync();
                result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
                    .ExecuteAsync(connectionTimeoutCancellation.Token);
            }
            catch (MsalUiRequiredException)
            {
                result = await app.AcquireTokenWithDeviceCode(scopes, deviceCodeResult => CustomDeviceFlowCallback(deviceCodeResult))
                    .ExecuteAsync(connectionTimeoutCancellation.Token);
            }

            return new SqlAuthenticationToken(result.AccessToken, result.ExpiresOn);
        }

        public override bool IsSupported(SqlAuthenticationMethod authenticationMethod)
            => authenticationMethod.Equals(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow);

        private static Task CustomDeviceFlowCallback(DeviceCodeResult result)
        {
            Console.WriteLine(result.Message);
            return Task.CompletedTask;
        }
    }

    public class Program
    {
        public static void Main()
        {
            // Register our custom authentication provider class to override Active Directory Device Code Flow
            SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow, new CustomDeviceCodeFlowAzureAuthenticationProvider());
            using (SqlConnection sqlConnection = new SqlConnection("Server=<myserver>.database.windows.net;Authentication=Active Directory Device Code Flow;Database=<db>;"))
            {
                sqlConnection.Open();
                Console.WriteLine("Connected successfully!");
            }
        }
    }
}

Além de melhorar a experiência de autenticação, Active Directory Interactive 2.1.0 e posterior fornecem as seguintes APIs para aplicativos cliente personalizarem a autenticação interativa e a autenticação de fluxo de código de dispositivo.

public class ActiveDirectoryAuthenticationProvider
{
    // For .NET Framework targeted applications only
    // Sets a reference to the current System.Windows.Forms.IWin32Window that triggers
    // the browser to be shown. 
    // Used to center the browser pop-up onto this window.
    public void SetIWin32WindowFunc(Func<IWin32Window> iWin32WindowFunc);

    // For .NET Standard targeted applications only
    // Sets a reference to the ViewController (if using .NET for iOS), Activity
    // (if using .NET for Android) IWin32Window, or IntPtr (if using .NET Framework). 
    // Used for invoking the browser for Active Directory Interactive authentication.
    public void SetParentActivityOrWindowFunc(Func<object> parentActivityOrWindowFunc);

    // For .NET Framework, .NET Core, and .NET Standard targeted applications
    // Sets a callback method that's invoked with a custom web UI instance that lets
    // the user sign in with Azure AD, present consent if needed, and get back the
    // authorization code. 
    // Applicable when working with Active Directory Interactive authentication.
    public void SetAcquireAuthorizationCodeAsyncCallback(Func<Uri, Uri, CancellationToken,
                                       Task<Uri>> acquireAuthorizationCodeAsyncCallback);

    // For .NET Framework, .NET Core, and .NET Standard targeted applications
    // Clears cached user tokens from the token provider.
    public static void ClearUserTokenCache();
}

Ver também