Udostępnij za pośrednictwem


Nawiązywanie połączenia z usługą Azure SQL przy użyciu uwierzytelniania microsoft Entra i programu SqlClient

Dotyczy: .NET Framework .NET .NET Standard

pobierz ADO.NET

W tym artykule opisano sposób nawiązywania połączenia ze źródłami danych usługi Azure SQL przy użyciu uwierzytelniania firmy Microsoft Entra z poziomu aplikacji .NET za pomocą programu SqlClient.

Uwaga

Chociaż identyfikator Entra firmy Microsoft to nowa nazwa usługi Azure Active Directory (Azure AD), aby zapobiec zakłócaniu działania istniejących środowisk, usługa Azure AD nadal pozostaje w niektórych zakodowanych na stałe elementach, takich jak pola interfejsu użytkownika, dostawcy połączeń, kody błędów i polecenia cmdlet. W tym artykule dwie nazwy są wymienne.

Przegląd

Uwierzytelnianie Entra firmy Microsoft używa tożsamości w usłudze Microsoft Entra ID do uzyskiwania dostępu do źródeł danych, takich jak Azure SQL Database, Azure SQL Managed Instance i Azure Synapse Analytics. Przestrzeń nazw Microsoft.Data.SqlClient umożliwia aplikacjom klienckim określanie poświadczeń usługi Microsoft Entra w różnych trybach uwierzytelniania podczas nawiązywania połączenia z usługami Azure SQL Database i Azure SQL Managed Instance. Aby korzystać z uwierzytelniania entra firmy Microsoft w usłudze Azure SQL, należy skonfigurować uwierzytelnianie usługi Microsoft Entra i zarządzać nim za pomocą usługi Azure SQL.

Po ustawieniu właściwości połączenia Authentication w parametrach połączenia klient może wybrać preferowany tryb uwierzytelniania firmy Microsoft Entra zgodnie z podaną wartością:

  • Najwcześniejsza wersja Microsoft.Data.Sql Client obsługuje Active Directory Password dla programów .NET Framework, .NET Core i .NET Standard. Obsługuje również uwierzytelnianie Active Directory Integrated i uwierzytelnianie Active Directory Interactive dla programu .NET Framework.

  • Począwszy od Microsoft.Data.SqlClient 2.0.0, obsługa uwierzytelniania Active Directory Integrated i uwierzytelniania Active Directory Interactive jest rozszerzona w programach .NET Framework, .NET Core i .NET Standard.

    Nowy tryb uwierzytelniania Active Directory Service Principal jest również dodawany w programie SqlClient 2.0.0. Korzysta z identyfikatora klienta i tajnego klucza tożsamości głównej usługi w celu przeprowadzenia uwierzytelniania.

  • Więcej trybów uwierzytelniania dodano w Microsoft.Data.SqlClient 2.1.0, w tym Active Directory Device Code Flow i Active Directory Managed Identity (znanych również jako Active Directory MSI). Te nowe tryby umożliwiają aplikacji uzyskanie tokenu dostępu w celu nawiązania połączenia z serwerem.

Aby uzyskać informacje na temat uwierzytelniania Microsoft Entra poza opisem poniższych sekcji, zobacz Use Microsoft Entra authentication.

Ustawianie uwierzytelniania w usłudze Microsoft Entra

Gdy aplikacja łączy się ze źródłami danych usługi Azure SQL przy użyciu uwierzytelniania firmy Microsoft Entra, musi zapewnić prawidłowy tryb uwierzytelniania. W poniższej tabeli wymieniono obsługiwane tryby uwierzytelniania. Aplikacja określa tryb przy użyciu właściwości połączenia Authentication w parametrach połączenia.

Wartość Opis Microsoft.Data.SqlClient, wersja
Hasło usługi Active Directory Uwierzytelnij się za pomocą nazwy użytkownika i hasła tożsamości Microsoft Entra 1.0+
Zintegrowana z usługą Active Directory Uwierzytelniaj się za pomocą tożsamości Microsoft Entra przy użyciu zintegrowanego uwierzytelniania systemu Windows (IWA) 2.0.0+1
Interaktywna usługa Active Directory Uwierzytelnij się za pomocą tożsamości Microsoft Entra korzystając z uwierzytelniania interaktywnego 2.0.0+1
Podmiot usługi Active Directory Uwierzytelnij się za pomocą jednostki usługi Entra firmy Microsoft, używając jej ID klienta oraz tajnego klucza. 2.0.0+
Przepływ kodu urządzenia Active Directory Uwierzytelnij się za pomocą tożsamości Entra firmy Microsoft, używając trybu przepływu kodu urządzenia. 2.1.0+
Zarządzana tożsamość Active Directory
Usługa MSI w Active Directory
Uwierzytelnij się za pomocą tożsamości zarządzanej przypisanej przez system lub użytkownika Microsoft Entra 2.1.0+
Domyślna usługa Active Directory Uwierzytelnij się za pomocą tożsamości Microsoft Entra, korzystając z mechanizmów bez hasła i nieinterakcyjnych, takich jak tożsamości zarządzane, Visual Studio Code, Visual Studio, Azure CLI itp. 3.0.0+
Tożsamość obciążeń w Active Directory Uwierzytelnianie za pomocą tożsamości Microsoft Entra przy użyciu federacyjnej tożsamości zarządzanej przypisanej użytkownikowi do połączenia z bazą danych SQL ze środowisk klienckich w Azure, które obsługują tożsamość obciążenia. 5.2.0+

1 Przed Microsoft.Data.SqlClient 2.0.0, Active Directory Integratedi tryby uwierzytelniania Active Directory Interactive są obsługiwane tylko w programie .NET Framework.

Korzystanie z uwierzytelniania za pomocą hasła

Active Directory Password tryb uwierzytelniania obsługuje uwierzytelnianie źródeł danych platformy Azure przy użyciu identyfikatora Entra firmy Microsoft dla użytkowników natywnych lub federacyjnych firmy Microsoft Entra. W przypadku korzystania z tego trybu poświadczenia użytkownika muszą być podane w parametrach połączenia. W poniższym przykładzie pokazano, jak używać uwierzytelniania Active Directory Password.

// 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();
}

Korzystanie ze zintegrowanego uwierzytelniania

Aby użyć trybu uwierzytelniania Active Directory Integrated, musisz mieć lokalne wystąpienie usługi Active Directory, które jest przyłączone do identyfikatora Entra firmy Microsoft w chmurze. Możesz federować przy użyciu usług Active Directory Federation Services (AD FS), na przykład.

Kiedy jesteś zalogowany do komputera przyłączonego do domeny, w tym trybie możesz uzyskać dostęp do źródeł danych usługi Azure SQL bez konieczności podawania poświadczeń. Nie można określić nazwy użytkownika i hasła w parametrach połączenia dla aplikacji .NET Framework. Nazwa użytkownika jest opcjonalna w parametrach połączenia dla aplikacji .NET Core i .NET Standard. Nie można ustawić właściwości Credential programu SqlConnection w tym trybie.

Poniższy fragment kodu jest przykładem użycia uwierzytelniania Active Directory Integrated.

// 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();
}

Korzystanie z uwierzytelniania interakcyjnego

Active Directory Interactive uwierzytelnianie obsługuje technologię wieloskładnikowego uwierzytelniania do łączenia się ze źródłami danych Azure SQL. Jeśli podasz ten tryb uwierzytelniania w parametrach połączenia, zostanie wyświetlony ekran uwierzytelniania platformy Azure i poprosi użytkownika o wprowadzenie prawidłowych poświadczeń. Nie można określić hasła w parametrach połączenia.

Nie można ustawić właściwości Credential programu SqlConnection w tym trybie. W przypadku Microsoft.Data.SqlClient 2.0.0 i nowszych nazwa użytkownika jest dozwolona w parametrach połączenia w trybie interaktywnym.

W poniższym przykładzie pokazano, jak używać uwierzytelniania Active Directory Interactive.

// 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();
}

Korzystanie z uwierzytelniania jednostki usługi

W trybie uwierzytelniania Active Directory Service Principal aplikacja kliencka może łączyć się ze źródłami danych usługi Azure SQL, podając identyfikator klienta i klucz tajny tożsamości obiektu głównego usługi. Uwierzytelnianie podmiotu usługi obejmuje:

  1. Konfigurowanie rejestracji aplikacji przy użyciu tajnego klucza.
  2. Udzielanie uprawnień aplikacji w wystąpieniu usługi Azure SQL Database.
  3. Nawiązywanie połączenia przy użyciu poprawnych danych uwierzytelniających.

W poniższym przykładzie pokazano, jak używać uwierzytelniania Active Directory Service Principal.

// 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();
}

Korzystanie z uwierzytelniania przy użyciu kodu urządzenia

Dzięki biblioteki Microsoft Authentication Library dla platformy .NET (MSAL.NET) uwierzytelnianie Active Directory Device Code Flow umożliwia aplikacji klienckiej łączenie się ze źródłami danych Usługi Azure SQL z urządzeń i systemów operacyjnych, które nie mają interaktywnej przeglądarki internetowej. Uwierzytelnianie interakcyjne jest wykonywane na innym urządzeniu. Aby uzyskać więcej informacji na temat procesu uwierzytelniania kodu urządzenia, zobacz proces uwierzytelniania kodu urządzenia OAuth 2.0.

Gdy ten tryb jest używany, nie można ustawić właściwości Credential dla SqlConnection. Ponadto nazwa użytkownika i hasło nie mogą być określone w parametrach połączenia.

Poniższy fragment kodu jest przykładem użycia uwierzytelniania Active Directory Device Code Flow.

Uwaga

Limit czasu dla Active Directory Device Code Flow jest domyślny dla ustawienia Connect Timeout połączenia. Upewnij się, że określono Connect Timeout, który zapewnia wystarczająco dużo czasu na przeprowadzenie procesu uwierzytelniania przy użyciu kodu urządzenia.

// 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();
}

Korzystanie z uwierzytelniania tożsamości zarządzanej

Uwierzytelnianie przy użyciu tożsamości zarządzanych dla zasobów platformy Azure jest zalecaną metodą uwierzytelniania w celu programowego dostępu do bazy danych SQL. Aplikacja kliencka może używać przypisanej przez system lub przypisanej przez użytkownika tożsamości zarządzanej zasobu do uwierzytelniania w usłudze SQL przy użyciu identyfikatora Entra firmy Microsoft, podając tożsamość i używając jej do uzyskiwania tokenów dostępu. Ta metoda eliminuje konieczność zarządzania poświadczeniami i wpisami tajnymi oraz może uprościć zarządzanie dostępem.

Istnieją dwa typy tożsamości zarządzanych:

  • Tożsamość zarządzana przydzielona przez system jest tworzona jako część zasobu platformy Azure (takiego jak Twoje wystąpienie zarządzane SQL lub serwera logicznego) i dzieli cykl życia tego zasobu. Tożsamości przypisane przez system mogą być skojarzone tylko z pojedynczym zasobem platformy Azure.
  • tożsamość przypisana przez użytkownika i zarządzana jest tworzona jako autonomiczny zasób usługi Microsoft Azure. Można ją przypisać do jednego lub więcej wystąpień usługi Azure.

Aby uzyskać więcej informacji na temat tożsamości zarządzanych, zobacz Informacje o tożsamościach zarządzanych dla zasobów platformy Azure.

Od wersji Microsoft.Data.SqlClient 2.1.0, sterownik obsługuje uwierzytelnianie w usługach Azure SQL Database, Azure Synapse Analytics i Azure SQL Managed Instance dzięki uzyskiwaniu tokenów dostępu za pośrednictwem tożsamości zarządzanej. Aby użyć tego uwierzytelniania, określ Active Directory Managed Identity lub Active Directory MSI w parametrach połączenia, a hasło nie jest wymagane. Nie można też ustawić właściwości Credential dla SqlConnection w tym trybie.

W przypadku tożsamości zarządzanej przypisanej przez użytkownika identyfikator klienta tożsamości zarządzanej należy podać podczas korzystania z programu Microsoft.Data.SqlClient w wersji 3.0 lub nowszej. W przypadku korzystania z programu Microsoft.Data.SqlClient w wersji 2.1 należy podać identyfikator obiektu tożsamości zarządzanej.

W poniższym przykładzie pokazano, jak używać uwierzytelniania Active Directory Managed Identity przy użyciu tożsamości zarządzanej przypisanej przez system.

// 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();
}

W poniższym przykładzie pokazano, Active Directory Managed Identity uwierzytelnianie przy użyciu tożsamości zarządzanej przypisanej przez użytkownika przy użyciu Microsoft.Data.SqlClient w wersji 3.0 lub nowszej.

// 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();
}

W poniższym przykładzie pokazano Active Directory Managed Identity uwierzytelniania przy użyciu tożsamości zarządzanej przypisanej przez użytkownika z 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();
}

Korzystanie z uwierzytelniania domyślnego

Dostępny od wersji 3.0 ten tryb uwierzytelniania rozszerza możliwości uwierzytelniania użytkowników. Ten tryb rozszerza rozwiązania logowania do środowiska klienta, programu Visual Studio Code, programu Visual Studio, interfejsu wiersza polecenia Azure itp.

W tym trybie uwierzytelniania sterownik uzyskuje token, przekazując element "DefaultAzureCredential" z biblioteki tożsamości platformy Azure w celu uzyskania tokenu dostępu. Ten tryb próbuje użyć zestawu typów poświadczeń, aby uzyskać token dostępu w określonej kolejności. W zależności od używanej wersji biblioteki tożsamości platformy Azure zestaw poświadczeń różni się. Różnice specyficzne dla wersji są zanotowane na liście. Aby uzyskać informacje o zachowaniu specyficznym dla wersji usługi Azure Identity, zobacz dokumentację interfejsu API azure.identity .

Ważne

Domyślna usługa Active Directory to wygodna opcja upraszczania różnic parametrów połączenia między różnymi środowiskami. Jednak może to wpływać na wydajność, ponieważ musi przeszukiwać wiele miejsc, aby znaleźć informacje o uwierzytelnianiu. Jeśli widzisz niską szybkość połączenia przy użyciu domyślnej usługi Active Directory, użyj innej opcji uwierzytelniania, która jest przeznaczona dla metody uwierzytelniania używanej w danym środowisku. "Domyślne ustawienia Active Directory" nie są zalecane w środowiskach, które mają ścisłe czasy reakcji na poziomie serwisu.

  • Poświadczenie środowiskowe
    • Włącza uwierzytelnianie za pomocą Microsoft Entra ID, używając klienta i tajnego klucza lub nazwy użytkownika i hasła, które są skonfigurowane w następujących zmiennych środowiskowych: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_CLIENT_CERTIFICATE_PATH, AZURE_USERNAME, AZURE_PASSWORD (więcej szczegółów)
  • WorkloadIdentityCredential
    • Umożliwia uwierzytelnianie Microsoft Entra Workload ID na platformie Kubernetes i innych hostach obsługujących tożsamość zadań. Aby uzyskać więcej informacji, zobacz Identyfikator Obciążenia Microsoft Entra. Dostępne począwszy od usługi Azure Identity w wersji 1.10 i Microsoft.Data.SqlClient 5.1.4.
  • ManagedIdentityCredential
    • Próba uwierzytelnienia za pomocą Microsoft Entra ID przy użyciu tożsamości zarządzanej przypisanej do środowiska wdrażania. "Identyfikator klienta" tożsamości zarządzanej przypisanej przez użytkownika jest odczytywany z właściwości połączenia "Identyfikator użytkownika".
  • Poświadczenie SharedTokenCache
    • Uwierzytelnianie odbywa się przy użyciu tokenów w lokalnej pamięci podręcznej udostępnionej między aplikacjami firmy Microsoft.
  • VisualStudioCredential
    • Włącza uwierzytelnianie przy użyciu identyfikatora Entra firmy Microsoft przy użyciu danych z programu Visual Studio
  • VisualStudioCodeCredential
    • Włącza uwierzytelnianie za pomocą identyfikatora Entra firmy Microsoft przy użyciu danych z programu Visual Studio Code.
  • AzurePowerShellCredential
    • Włącza uwierzytelnianie przy użyciu identyfikatora Entra firmy Microsoft przy użyciu programu Azure PowerShell. Dostępne począwszy od usługi Azure Identity w wersji 1.6 i Microsoft.Data.SqlClient 5.0.
  • AzureCliCredential
    • Umożliwia uwierzytelnianie przy użyciu identyfikatora Entra firmy Microsoft przy użyciu interfejsu wiersza polecenia platformy Azure w celu uzyskania tokenu dostępu.
  • AzureDeveloperCliCredential
    • Umożliwia uwierzytelnianie w usłudze Microsoft Entra ID przy użyciu interfejsu wiersza polecenia dla deweloperów platformy Azure w celu uzyskania tokenu dostępu. Dostępne począwszy od usługi Azure Identity w wersji 1.10 i Microsoft.Data.SqlClient 5.1.4.

Uwaga

InteractiveBrowserCredential jest wyłączony w implementacji sterownika usługi Active Directory Default, a Active Directory Interactive jest jedyną opcją dostępną do uzyskania tokenu przy użyciu uwierzytelniania wieloskładnikowego/interakcyjnego.

Dalsze opcje dostosowywania nie są obecnie dostępne.

W poniższym przykładzie pokazano, jak używać uwierzytelniania domyślnego usługi Active 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();
}

Korzystanie z uwierzytelniania tożsamości dla obciążenia roboczego

Dostępne począwszy od wersji 5.2, podobnie jak w przypadku tożsamości zarządzanych, tryb uwierzytelniania tożsamości obciążenia używa wartości parametru User ID w łańcuchu połączenia jako identyfikatora klienta, jeśli został określony. Jednak w przeciwieństwie do tożsamości zarządzanej parametr WorkloadIdentityCredentialOptions domyślnie jest wartością ze zmiennych środowiskowych: AZURE_TENANT_ID, AZURE_CLIENT_ID i AZURE_FEDERATED_TOKEN_FILE. Jednak tylko identyfikator klienta może zostać zastąpiony przez parametry połączenia.

W poniższym przykładzie pokazano uwierzytelnianie Active Directory Workload Identity przy użyciu tożsamości zarządzanej przypisanej przez użytkownika z Microsoft.Data.SqlClient v5.2 i nowsze.

// 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();
}

Dostosowywanie uwierzytelniania Microsoft Entra

Oprócz korzystania z uwierzytelniania Entra firmy Microsoft wbudowanego w sterownik Microsoft.Data.SqlClient 2.1.0 i nowszych udostępniaj aplikacjom opcję dostosowywania uwierzytelniania firmy Microsoft Entra. Dostosowanie jest oparte na klasie ActiveDirectoryAuthenticationProvider, która pochodzi z klasy abstrakcyjnej SqlAuthenticationProvider.

Podczas uwierzytelniania firmy Microsoft aplikacja kliencka może zdefiniować własną klasę ActiveDirectoryAuthenticationProvider za pomocą jednej z następujących metod:

  • Przy użyciu dostosowanej metody wywołania zwrotnego.
  • Przekazywanie identyfikatora klienta aplikacji do biblioteki MSAL za pośrednictwem sterownika SqlClient w celu pobierania tokenów dostępu.

W poniższym przykładzie pokazano, jak używać niestandardowego wywołania zwrotnego, gdy uwierzytelnianie Active Directory Device Code Flow jest używane.

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

namespace CustomAuthenticationProviderExamples
{
    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);
        }
    }
}

W przypadku niestandardowej klasy ActiveDirectoryAuthenticationProvider, identyfikator klienta aplikacji zdefiniowanej przez użytkownika można przekazać do SqlClient, gdy jest używany obsługiwany tryb uwierzytelniania Microsoft Entra. Obsługiwane tryby uwierzytelniania Microsoft Entra obejmują Active Directory Password, Active Directory Integrated, Active Directory Interactive, Active Directory Service Principali Active Directory Device Code Flow.

Identyfikator klienta aplikacji można również konfigurować za pośrednictwem SqlAuthenticationProviderConfigurationSection lub SqlClientAuthenticationProviderConfigurationSection. Właściwość konfiguracji applicationClientId dotyczy programów .NET Framework 4.6+ i .NET Core 2.1+.

Poniższy fragment kodu to przykład użycia dostosowanej klasy ActiveDirectoryAuthenticationProvider z identyfikatorem klienta aplikacji zdefiniowanym przez użytkownika, gdy używane jest uwierzytelnianie Active Directory Interactive.

using System;
using Microsoft.Data.SqlClient;

namespace CustomAuthenticationProviderExamples
{
    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!");
            }
        }
    }
}

W poniższym przykładzie pokazano, jak ustawić identyfikator klienta aplikacji za pomocą sekcji konfiguracji.

<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>

Korzystanie z AccessTokenCallback

Od wersji 5.2 dostępna jest nowa właściwość AccessTokenCallback we właściwości SqlConnection. Użyj właściwości AccessTokenCallback, aby zdefiniować funkcję niestandardową, która zwraca token dostępu, biorąc pod uwagę parametry przychodzące. Użycie wywołania zwrotnego jest lepsze niż użycie właściwości AccessToken, ponieważ umożliwia odświeżanie tokenu dostępu w puli połączeń. W przypadku korzystania z właściwości AccessToken nie można zaktualizować tokenu po otwarciu połączenia. Nie ma również skojarzonej daty wygaśnięcia podanej za pośrednictwem właściwości . Po wygaśnięciu tokenu nowe żądania połączenia kończą się niepowodzeniem z powodu błędu uwierzytelniania serwera i pul przy użyciu tego tokenu muszą zostać wyczyszczone ręcznie.

Ważne

Musi zwracać tokeny dostępu o tym samym kontekście zabezpieczeń dla tych samych parametrów wejściowych. Jeśli kontekst zabezpieczeń jest inny, dla żądania połączenia może zostać zwrócone połączenie w puli z niewłaściwym kontekstem zabezpieczeń.

Uwaga

AccessTokenCallback jest częścią klucza używanego do identyfikowania pul połączeń. Unikaj tworzenia nowego wywołania zwrotnego funkcji za każdym razem, gdy tworzysz SqlConnection, ponieważ powoduje to utworzenie nowej puli przy każdej operacji. Odwołaj się do tego samego wystąpienia funkcji dla połączeń, które mają być brane pod uwagę przy tworzeniu puli. Klucz puli połączeń zawiera parametry przekazane do callbacku, aby zrealizować odpowiedni podział pul połączeń.

Poniższy fragment kodu jest przykładem użycia właściwości AccessTokenCallback w Microsoft.Data.SqlClient od wersji 5.2.

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);
        }
    }
}

Obsługa niestandardowego dostawcy uwierzytelniania SQL

Dzięki większej elastyczności aplikacja kliencka może używać własnego dostawcy do uwierzytelniania przez Microsoft Entra, zamiast korzystać z klasy ActiveDirectoryAuthenticationProvider. Niestandardowy dostawca uwierzytelniania musi być podklasą SqlAuthenticationProvider z zastąpionymi metodami. Następnie musi zarejestrować niestandardowego dostawcę, przesłaniając jedną lub więcej istniejących metod uwierzytelniania Active Directory*.

Ważne

Dostawca uwierzytelniania musi zwracać tokeny dostępu w tym samym kontekście zabezpieczeń dla tych samych parametrów wejściowych. Jeśli kontekst zabezpieczeń jest inny, dla żądania połączenia może zostać zwrócone połączenie w puli z niewłaściwym kontekstem zabezpieczeń.

W poniższym przykładzie pokazano, jak używać nowego dostawcy uwierzytelniania na potrzeby uwierzytelniania 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 CustomAuthenticationProviderExamples
{
    /// <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!");
            }
        }
    }
}

Oprócz poprawy doświadczenia uwierzytelniania Active Directory Interactive, Microsoft.Data.SqlClient w wersji 2.1.0 i nowszych udostępnia następujące interfejsy API dla aplikacji klienckich, umożliwiające dostosowanie uwierzytelniania interaktywnego oraz uwierzytelniania za pomocą przepływu kodu urządzenia.

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();
}

Zobacz też