分享方式:


使用 Microsoft Entra 驗證來連線

下載 JDBC 驅動程式

此文章提供如何開發 Java 應用程式,以搭配 Microsoft JDBC Driver for SQL Server 使用 Microsoft Entra 驗證功能的相關資訊。

您可以使用 Microsoft Entra 驗證,這是 Microsoft Entra ID 中的身分識別連線到 Azure SQL 資料庫、Azure SQL 受控執行個體及 Azure Synapse Analytics 的機制。 使用 Microsoft Entra 驗證集中管理資料庫使用者的身分識別,並作為 SQL Server 的替代驗證。 JDBC 驅動程式可讓您在連線到 Azure SQL 的 JDBC 連接字串中指定 Microsoft Entra 認證。 如需如何設定 Microsoft Entra 驗證的相關資訊,請造訪使用 Microsoft Entra 驗證連線至 Azure SQL

在 Microsoft JDBC Driver for SQL Server 中,對 Microsoft Entra 驗證提供支援的連接屬性為:

  • 驗證:使用此屬性來指出要用於連線的 SQL 驗證方法。 可能的值包括:
    • ActiveDirectoryManagedIdentity

      • 從驅動程式 8.3.1 版開始,便可以使用 authentication=ActiveDirectoryMSI 從已啟用「身分識別」支援的 Azure 資源連線到 Azure SQL 資料庫/Synapse Analytics。 此外,使用此驗證模式時,您也可以在 Connection/DataSource 屬性中指定 msiClientIdmsiClientId 必須包含受控識別的用戶端識別碼,以便用來取得 accessToken 以用於建立連線。 從驅動程式 v12.2 版開始,也可以使用 authentication=ActiveDirectoryManagedIdentity 從已啟用「身分識別」支援的 Azure 資源連線到 Azure SQL 資料庫/Synapse Analytics。 此外,您現在也可以在 user 屬性中設定受控識別的用戶端識別碼。 如需詳細資訊,請參閱使用 ActiveDirectoryManagedIdentity 驗證模式來連線
    • ActiveDirectoryDefault

      • 從驅動程式 12.2.版開始,便可以使用 authentication=ActiveDirectoryDefault 來透過 Azure 身分識別用戶端程式庫內的 DefaultAzureCredential 連線到 Azure SQL/Synapse Analytics。 如需詳細資訊,請參閱使用 ActiveDirectoryDefault 驗證模式來連線
    • ActiveDirectoryIntegrated

      • 從驅動程式 6.0 版開始,便可以使用 authentication=ActiveDirectoryIntegrated 透過整合式驗證來連線到 Azure SQL/Synapse Analytics。 若要使用此驗證模式,您必須將內部部署 Active Directory 同盟服務 (ADFS) 與雲端中的 Microsoft Entra ID 建立同盟。 在您設定完成後,您可以透過將原生程式庫 mssql-jdbc_auth-<version>-<arch>.dll 新增至 Windows 上的應用程式類別路徑,或透過為跨平台驗證支援設定 Kerberos 票證,從而進行連線。 登入已加入網域的電腦之後,您就能夠在系統不提示輸入認證的情況下存取 Azure SQL/Azure Synapse Analytics。 如需詳細資訊,請參閱使用 ActiveDirectoryIntegrated 驗證模式來連線
    • ActiveDirectoryPassword

      • 從驅動程式 6.0 版本開始,便可以使用 authentication=ActiveDirectoryPassword 透過 Microsoft Entra 使用者名稱和密碼來連線到 Azure SQL/Synapse Analytics。 如需詳細資訊,請參閱使用 ActiveDirectoryPassword 驗證模式來連線
    • ActiveDirectoryInteractive

    • ActiveDirectoryServicePrincipal

      • 從驅動程式 9.2 版開始,便可以使用 authentication=ActiveDirectoryServicePrincipal 來連線到 Azure SQL/Synapse Analytics,方法是在 userName 屬性中指定應用程式/用戶端識別碼,並在 password 屬性中指定服務主體身分識別的密碼。 如需詳細資訊,請參閱使用 ActiveDirectoryServicePrincipal 驗證模式來連線
    • ActiveDirectoryServicePrincipalCertificate

      • 從驅動程式 12.4 版開始,便可以使用 authentication=ActiveDirectoryServicePrincipalCertificate 來連線到 Azure SQL 資料庫/Synapse Analytics,方法是在 userName 屬性中指定應用程式/用戶端識別碼,並在 clientCertificate 屬性中指定服務主體認證的位置。 如需詳細資訊,請參閱使用 ActiveDirectoryServicePrincipalCertificate 驗證模式來連線
    • SqlPassword

      • 使用 authentication=SqlPassword 來連線至使用 userName/user 和 password 屬性的 SQL Server。
    • NotSpecified

      • 當不需要這些驗證方法時,請使用 authentication=NotSpecified 或將其保留為預設值。
    • accessToken:使用此連線屬性可透過存取權杖來連線到 SQL Database。 accessToken 只能使用 DriverManager 類別中 getConnection() 方法的 Properties 參數來設定。 其不能用於連線 URL 中。

如需詳細資訊,請參閱設定連接屬性頁面的驗證屬性。

用戶端安裝需求

除了基本驅動程式系統需求之外,下列驗證模式還有更多需求。

下列表格清單列出每個驗證模式和驅動程式版本所需的程式庫相依性。 相依性的相依性也是必要的。

注意

如果主要版本的 Hotfix 與其主要版本不同的相依性版本,也會列出 Hotfix。

驗證選項 驅動程式版本 程式庫相依性
ActiveDirectoryPassword
ActiveDirectoryIntegrated
6.0 Adal4j 1.3.0
ActiveDirectoryPassword
ActiveDirectoryIntegrated
6.2.2 - 6.4 Adal4j 1.4.0
ActiveDirectoryPassword
ActiveDirectoryIntegrated
7.0 Adal4j 1.6.0
ActiveDirectoryPassword
ActiveDirectoryIntegrated
7.2 Adal4j 1.6.3
Client-Runtime-for-AutoRest 1.6.5
ActiveDirectoryPassword
ActiveDirectoryIntegrated
7.4 - 8.2 Adal4jl4j 1.6.4
Client-Runtime-for-AutoRest 1.7.0
ActiveDirectoryPassword
ActiveDirectoryIntegrated
8.4 Adal4j 1.6.5
Client-Runtime-for-AutoRest 1.7.4
ActiveDirectoryPassword
ActiveDirectoryIntegrated
ActiveDirectoryInteractive
ActiveDirectoryServicePrincipal
9.2 msal4j 1.7.1
ActiveDirectoryPassword
ActiveDirectoryIntegrated
ActiveDirectoryInteractive
ActiveDirectoryServicePrincipal
9.4 msal4j 1.10.1
ActiveDirectoryPassword
ActiveDirectoryIntegrated
ActiveDirectoryInteractive
ActiveDirectoryServicePrincipal
10.2 msal4j 1.11.0
ActiveDirectoryPassword
ActiveDirectoryIntegrated
ActiveDirectoryInteractive
ActiveDirectoryServicePrincipal
11.2 msal4j 1.11.3
ActiveDirectoryPassword
ActiveDirectoryIntegrated
ActiveDirectoryInteractive
ActiveDirectoryServicePrincipal
11.2.3 msal4j 1.13.0
ActiveDirectoryPassword
ActiveDirectoryIntegrated
ActiveDirectoryInteractive
ActiveDirectoryServicePrincipal
12.2 msal4j 1.13.3
ActiveDirectoryManagedIdentity
ActiveDirectoryMSI
ActiveDirectoryDefault
12.2 azure-identity 1.7.0
ActiveDirectoryPassword
ActiveDirectoryIntegrated
ActiveDirectoryInteractive
ActiveDirectoryServicePrincipal
ActiveDirectoryServicePrincipalCertificate
12.4 msal4j 1.13.8
ActiveDirectoryManagedIdentity
ActiveDirectoryMSI
ActiveDirectoryDefault
12.4 azure-identity 1.9.0
ActiveDirectoryPassword
ActiveDirectoryIntegrated
ActiveDirectoryInteractive
ActiveDirectoryServicePrincipal
ActiveDirectoryServicePrincipalCertificate
12.6 msal4j 1.14.1
ActiveDirectoryManagedIdentity
ActiveDirectoryMSI
ActiveDirectoryDefault
12.6 azure-identity 1.11.1
ActiveDirectoryPassword
ActiveDirectoryIntegrated
ActiveDirectoryInteractive
ActiveDirectoryServicePrincipal
ActiveDirectoryServicePrincipalCertificate
12.6.3 msal4j 1.15.1
ActiveDirectoryManagedIdentity
ActiveDirectoryMSI
ActiveDirectoryDefault
12.6.3 azure-identity 1.12.2
ActiveDirectoryPassword
ActiveDirectoryIntegrated
ActiveDirectoryInteractive
ActiveDirectoryServicePrincipal
ActiveDirectoryServicePrincipalCertificate
12.6.4 msal4j 1.15.1
ActiveDirectoryManagedIdentity
ActiveDirectoryMSI
ActiveDirectoryDefault
12.6.4 azure-identity 1.12.2
ActiveDirectoryPassword
ActiveDirectoryIntegrated
ActiveDirectoryInteractive
ActiveDirectoryServicePrincipal
ActiveDirectoryServicePrincipalCertificate
12.8 msal4j 1.15.1
ActiveDirectoryManagedIdentity
ActiveDirectoryMSI
ActiveDirectoryDefault
12.8 azure-identity 1.12.2

使用 ActiveDirectoryManagedIdentity 驗證模式來連線

從 7.2 版開始,支援此驗證模式。 若要使用此模式,請指定 authentication=ActiveDirectoryMSI。 從 12.2 版開始,也可以指定 authentication=ActiveDirectoryManagedIdentity

除了用戶端設定需求中列出的程式庫相依性需求之外,這項功能還有下列需求:

下列範例示範如何使用 authentication=ActiveDirectoryManagedIdentity 模式。 請從設定用於受控識別的 Azure 資源內執行此範例。

若要執行範例,請以您的伺服器/資料庫名稱取代下列幾行中的伺服器/資料庫名稱:

ds.setServerName("msentra-managed-demo.database.windows.net"); // replace 'msentra-managed-demo' with your server name
ds.setDatabaseName("demo"); // replace with your database name
//Optional
ds.setMSIClientId("<managed_identity_client>"); // Replace with Client ID of user-assigned managed identity to be used

使用 ActiveDirectoryMSI 驗證模式的範例:

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerDataSource;

public class MsEntraMSI {
    public static void main(String[] args) throws Exception {

        SQLServerDataSource ds = new SQLServerDataSource();
        ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
        ds.setDatabaseName("demo"); // Replace with your database name
        ds.setAuthentication("ActiveDirectoryMSI");
        // Optional
        ds.setMSIClientId("<managed_identity_client_guid>"); // Replace with Client ID of user-assigned managed identity to be used

        try (Connection connection = ds.getConnection();
                Statement stmt = connection.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
            if (rs.next()) {
                System.out.println("You have successfully logged on as: " + rs.getString(1));
            }
        }
    }
}

下列範例示範如何使用 authentication=ActiveDirectoryManagedIdentity 模式。

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerDataSource;

public class MSEntraManagedIdentity {
    public static void main(String[] args) throws Exception {

        SQLServerDataSource ds = new SQLServerDataSource();
        ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
        ds.setDatabaseName("demo"); // Replace with your database name
        ds.setAuthentication("ActiveDirectoryManagedIdentity"); // ActiveDirectoryManagedIdentity for JDBC driver version v12.2.0+
        // Optional
        ds.setUser("<managed_identity_client>"); // Replace with Client ID of User-Assigned Managed Identity to be used

        try (Connection connection = ds.getConnection();
                Statement stmt = connection.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
            if (rs.next()) {
                System.out.println("You have successfully logged on as: " + rs.getString(1));
            }
        }
    }
}

在 Azure 虛擬機器上進行這些範例時,會從「系統指派的受控識別」或「使用者指派的受控識別」(如果已使用受控識別的用戶端識別碼指定 msiClientIduser) 擷取存取權杖,並使用所擷取的存取權杖建立連線。 如果已建立連線,您應該會看到下列訊息:

You have successfully logged on as: <your Managed Identity username>

使用 ActiveDirectoryDefault 驗證模式來連線

ActiveDirectoryDefault 驗證選項會使用 Azure 身分識別用戶端程式庫的 DefaultAzureCredential 鏈結 TokenCredential 實作。 該認證結合了鏈結在一起的常用驗證方法。

ActiveDirectoryDefault 驗證需要在執行階段相依於 Azure 身分識別用戶端程式庫,才能使用受控識別。 如需程式庫版本詳細資料,請參閱用戶端設定需求

下列資料表列出每個 JDBC 驅動程式版本的 DefaultAzureCredential 認證鏈結。

驅動程式版本 azure-identity 版本檔 DefaultAzureCredential 鏈結
12.2 azure-identity 1.7.0 Environment
受控識別
IntelliJ
Azure CLI
Azure PowerShell
12.4 azure-identity 1.9.0 Environment
工作負載身分識別
受控識別
Azure Developer CLI
IntelliJ
Azure CLI
Azure PowerShell
12.6 azure-identity 1.11.1 Environment
工作負載身分識別
受控識別
Azure Developer CLI
IntelliJ
Azure CLI
Azure PowerShell
12.8 azure-identity 1.12.2 Environment
工作負載身分識別
受控識別
Azure Developer CLI
IntelliJ
Azure CLI
Azure PowerShell

有許多變數可以設定為設定 Environment 認證。 如需設定 DefaulAzureCredential 鏈結的詳細資料 (包含 Environment 認證),請參閱上方資料表連結的相關 azure 身分識別檔版本。

若要在 Windows 上使用 IntellijCredential,請將環境變數 INTELLIJ_KEEPASS_PATH 設定為 keepass 檔案的位置。 例如: INTELLIJ_KEEPASS_PATH=C:\user\your\path\to\the\keepass\file

若要提供更多租用戶給 DefaultAzureCredential,請使用 ADDITIONALLY_ALLOWED_TENANTS 環境變數。 此變數會採用逗號分隔清單。 例如,ADDITIONALLY_ALLOWED_TENANTS=<your-tenant-id-0>,<your-tenant-id-1>,<your-tenant-id-2>,...

下列範例示範如何在 DefaultAzureCredential 內搭配 AzureCliCredential 使用 authentication=ActiveDirectoryDefault 模式。

  1. 請先使用下列命令登入 Azure CLI。

    az login
    
  2. 成功登入 Azure CLI 之後,請執行下列程式碼。

    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.Statement;
    
    import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
    
    public class MSEntraDefault {
        public static void main(String[] args) throws Exception {
    
            SQLServerDataSource ds = new SQLServerDataSource();
            ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
            ds.setDatabaseName("demo"); // Replace with your database name
            ds.setAuthentication("ActiveDirectoryDefault");
    
            try (Connection connection = ds.getConnection();
                    Statement stmt = connection.createStatement();
                    ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
                if (rs.next()) {
                    System.out.println("You have successfully logged on as: " + rs.getString(1));
                }
            }
        }
    }
    

使用 ActiveDirectoryIntegrated 驗證模式來連線

有兩種方式可在 Microsoft JDBC Driver for SQL Server 中使用 ActiveDirectoryIntegrated 驗證:

  • 在 Windows 上,可以將來自下載套件mssql-jdbc_auth-<version>-<arch>.dll 複製到系統路徑中的位置。
  • 如果您無法使用 DLL,則從 6.4 版開始,您可以設定 Kerberos 票證。 有多個平台 (Windows、Linux 和 macOS) 支援此方法。 如需詳細資訊,請參閱在 Windows、Linux 和 macOS 上設定 Kerberos 票證

請確定您有來自用戶端設定需求的必要相依程式庫。

下列範例示範如何使用 authentication=ActiveDirectoryIntegrated 模式。 此範例會在與 Microsoft Entra ID 同盟的已加入網域的機器上執行。 代表您 Windows 使用者的資料庫使用者必須存在於資料庫中,且必須有 CONNECT 權限。

在執行範例之前,請將下列行中的伺服器/資料庫名稱,取代為您的伺服器/資料庫名稱:

ds.setServerName("msentra-managed-demo.database.windows.net"); // replace 'msentra-managed-demo' with your server name
ds.setDatabaseName("demo"); // replace with your database name

使用 ActiveDirectoryIntegrated 驗證模式的範例:

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerDataSource;

public class MSEntraIntegrated {
    public static void main(String[] args) throws Exception {

        SQLServerDataSource ds = new SQLServerDataSource();
        ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
        ds.setDatabaseName("demo"); // Replace with your database name
        ds.setAuthentication("ActiveDirectoryIntegrated");

        try (Connection connection = ds.getConnection();
                Statement stmt = connection.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
            if (rs.next()) {
                System.out.println("You have successfully logged on as: " + rs.getString(1));
            }
        }
    }
}

執行此範例時,會自動使用來自用戶端平台的 Kerberos 票證,不需要密碼。 如果已建立連線,您應該會看到下列訊息:

You have successfully logged on as: <your domain user name>

在 Windows、Linux 和 macOS 上設定 Kerberos 票證

您必須設定 Kerberos 票證,以將目前使用者連結至 Windows 網域帳戶。 以下是重要步驟的摘要。

Windows

注意

在 Windows 上,可以使用來自下載套件mssql-jdbc_auth-<version>-<arch>.dll,而非使用這些 Kerberos 設定步驟。 只有在無法使用 DLL 時,才需要這些步驟。

JDK 隨附 kinit,可讓您在與 Microsoft Entra ID 建立同盟的已加入網域之機器上,從金鑰發佈中心 (KDC) 取得 TGT。

步驟 1:票證授權票證的擷取
  • 執行於:Windows

  • 動作

    • 使用命令 kinit username@DOMAIN.COMPANY.COM 從 KDC 取得 TGT,然後其會提示您輸入網域密碼。
    • 使用 klist 查看可用的票證。 如果 kinit 成功,您應該會看到 krbtgt/DOMAIN.COMPANY.COM@ DOMAIN.COMPANY.COM 的票證。

    注意

    您可能必須使用 -Djava.security.krb5.conf 指定 .ini 檔案,應用程式才能找到 KDC。

Linux 與 macOS

需求

存取已加入網域的 Windows 電腦,以查詢您的 Kerberos 網域控制站。

步驟 1:尋找 Kerberos KDC
  • 執行於:Windows 命令列

  • 動作nltest /dsgetdc:DOMAIN.COMPANY.COM (其中 DOMAIN.COMPANY.COM 對應至您網域名稱的位置)

  • 範例輸出

    DC: \\co1-red-dc-33.domain.company.com
    Address: \\2111:4444:2111:33:1111:ecff:ffff:3333
    ...
    The command completed successfully
    
  • 要擷取的資訊 DC 名稱,在此案例中為 co1-red-dc-33.domain.company.com

步驟 2:在 krb5.conf 中設定 KDC
  • 執行於:Linux/macOS

  • 動作:以您選擇的編輯器編輯 /etc/krb5.conf。 設定下列金鑰

    [libdefaults]
      default_realm = DOMAIN.COMPANY.COM
    
    [realms]
    DOMAIN.COMPANY.COM = {
       kdc = co1-red-dc-28.domain.company.com
    }
    

    然後,儲存 krb5.conf 檔案並結束

    注意

    網域必須全部為大寫。

步驟 3:測試票證授權票證的擷取
  • 執行於:Linux/macOS
  • 動作
    • 使用命令 kinit username@DOMAIN.COMPANY.COM 從 KDC 取得 TGT,然後其會提示您輸入網域密碼。
    • 使用 klist 查看可用的票證。 如果 kinit 成功,您應該會看到 krbtgt/DOMAIN.COMPANY.COM@ DOMAIN.COMPANY.COM 的票證。

使用 ActiveDirectoryPassword 驗證模式來連線

下列範例示範如何使用 authentication=ActiveDirectoryPassword 模式。

若要建置並執行範例:

  1. 請確定您有來自用戶端設定需求的必要相依程式庫。

  2. 找出下列幾行程式碼,並將伺服器/資料庫名稱取代為您的伺服器/資料庫名稱。

    ds.setServerName("msentra-managed-demo.database.windows.net"); // replace 'msentra-managed-demo' with your server name
    ds.setDatabaseName("demo"); // replace with your database name
    
  3. 找出下列幾行程式碼。 將使用者名稱取代為您想要以該身分連線的 Microsoft Entra 使用者名稱。

    ds.setUser("bob@example.com"); // replace with your username
    ds.setPassword("password");     // replace with your password
    

使用 ActiveDirectoryPassword 驗證模式的範例:

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerDataSource;

public class MSEntraUserPassword {

    public static void main(String[] args) throws Exception{

        SQLServerDataSource ds = new SQLServerDataSource();
        ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
        ds.setDatabaseName("demo"); // Replace with your database
        ds.setUser("bob@example.com"); // Replace with your username
        ds.setPassword("password"); // Replace with your password
        ds.setAuthentication("ActiveDirectoryPassword");

        try (Connection connection = ds.getConnection();
                Statement stmt = connection.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
            if (rs.next()) {
                System.out.println("You have successfully logged on as: " + rs.getString(1));
            }
        }
    }
}

如果已建立連線,您應該會看到下列訊息作為輸出:

You have successfully logged on as: <your user name>

使用 ActiveDirectoryInteractive 驗證模式來連線

下列範例示範如何使用 authentication=ActiveDirectoryInteractive 模式。

若要建置並執行範例:

  1. 請確定您有來自用戶端設定需求的必要相依程式庫。

  2. 找出下列幾行程式碼,並將伺服器/資料庫名稱取代為您的伺服器/資料庫名稱。

    ds.setServerName("msentra-managed-demo.database.windows.net"); // replace 'msentra-managed-demo' with your server name
    ds.setDatabaseName("demo"); // replace with your database name
    
  3. 找出下列幾行程式碼。 將使用者名稱取代為您想要以該身分連線的 Microsoft Entra 使用者名稱。

    ds.setUser("bob@example.com"); // replace with your username
    

使用 ActiveDirectoryInteractive 驗證模式的範例:

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerDataSource;

public class MSEntraInteractive {
    public static void main(String[] args) throws Exception{

        SQLServerDataSource ds = new SQLServerDataSource();
        ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
        ds.setDatabaseName("demo"); // Replace with your database
        ds.setAuthentication("ActiveDirectoryInteractive");

        // Optional login hint
        ds.setUser("bob@example.com"); // Replace with your user name

        try (Connection connection = ds.getConnection();
                Statement stmt = connection.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
            if (rs.next()) {
                System.out.println("You have successfully logged on as: " + rs.getString(1));
            }
        }
    }
}

當您執行程式時,系統會顯示瀏覽器來驗證使用者。 您所看到的確切內容會取決於您設定 Microsoft Entra ID 的方式。 其不一定會包含多重要素驗證提示 (要求您輸入使用者名稱、密碼、PIN 或透過手機進行第二種裝置驗證)。 如果在同一個程式中完成多個互動式驗證要求,而驗證程式庫可以重複使用先前快取的驗證權杖,之後的要求甚至可能不會提示您進行驗證。

如需如何設定 Microsoft Entra ID 以要求多重要素驗證的資訊,請參閱開始在雲端中使用 Microsoft Entra 多重要素驗證

如需這些對話框的螢幕擷取畫面,請參閱使用 Microsoft Entra 多重要素驗證

如果使用者驗證成功完成,您應該會在瀏覽器中看到下列訊息:

Authentication complete. You can close the browser and return to the application.

此訊息只表示使用者驗證成功,但不一定有成功連線到伺服器。 返回應用程式時,如果系統已和伺服器建立連線,您應該會在輸出中看到下列訊息:

You have successfully logged on as: <your user name>

使用 ActiveDirectoryServicePrincipal 驗證模式來連線

下列範例示範如何使用 authentication=ActiveDirectoryServicePrincipal 模式。

若要建置並執行範例:

  1. 請確定您有來自用戶端設定需求的必要相依程式庫。

  2. 找出下列幾行程式碼,並將伺服器/資料庫名稱取代為您的伺服器/資料庫名稱。

    ds.setServerName("msentra-managed-demo.database.windows.net"); // replace 'msentra-managed-demo' with your server name
    ds.setDatabaseName("demo"); // replace with your database name
    
  3. 找出下列幾行程式碼。 將 principalId 的值取代為您想要以該身分連線的 Microsoft Entra 服務主體應用程式識別碼/用戶端識別碼。 將 principalSecret 的值取代為秘密。

    String principalId = "<service_principal_guid>"; // Replace with your Microsoft Entra service principal ID.
    String principalSecret = "..."; // Replace with your Microsoft Entra principal secret.
    
  4. 使用 setUsersetPassword (在 10.2 版和更新版本中) 以及 setAADSecurePrincipalIdsetAADSecurePrincipalSecret (在 9.4 版和更低版本中) 設定主體識別碼和主體密碼。

使用 ActiveDirectoryServicePrincipal 驗證模式的範例:

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerDataSource;

public class MSEntraServicePrincipal {
    public static void main(String[] args) throws Exception{
        String principalId = "<service_principal_guid>"; // Replace with your Microsoft Entra service principal ID.
        String principalSecret = "..."; // Replace with your Microsoft Entra principal secret.

        SQLServerDataSource ds = new SQLServerDataSource();
        ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
        ds.setDatabaseName("demo"); // Replace with your database
        ds.setAuthentication("ActiveDirectoryServicePrincipal");
        ds.setUser(principalId); // setAADSecurePrincipalId for JDBC Driver 9.4 and below
        ds.setPassword(principalSecret); // setAADSecurePrincipalSecret for JDBC Driver 9.4 and below 

        try (Connection connection = ds.getConnection();
                Statement stmt = connection.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
            if (rs.next()) {
                System.out.println("You have successfully logged on as: " + rs.getString(1));
            }
        }
    }
}

如果已建立連線,您應該會看到下列訊息作為輸出:

You have successfully logged on as: <your app/client ID>

使用 ActiveDirectoryServicePrincipalCertificate 驗證模式來連線

下列範例示範如何使用 authentication=ActiveDirectoryServicePrincipalCertificate 模式。

若要建置並執行範例:

  1. 請確定您有來自用戶端設定需求的必要相依程式庫。

  2. 找出下列幾行程式碼,並將伺服器/資料庫名稱取代為您的伺服器/資料庫名稱。

    ds.setServerName("msentra-managed-demo.database.windows.net"); // replace 'msentra-managed-demo' with your server name
    ds.setDatabaseName("demo"); // replace with your database name
    
  3. 找出下列幾行程式碼。 將 principalId 的值取代為您想要以該身分連線的 Microsoft Entra 服務主體應用程式識別碼/用戶端識別碼。 將 clientCertificate 的值取代為服務主體憑證的位置。

    String principalId = "<service_principal_guid>"; // Replace with your Microsoft Entra service principal ID.
    
    String clientCertificate = "..."; // Replace with the location for your Microsoft Entra service principal certificate.
    
  4. 如果之前提及之憑證需要密碼,請使用 10.2 版本和更新版本中的 setPassword 或 9.4 版本和更低版本中的 setAADSecurePrincipalSecret 來設定主體密碼。

  5. 如果憑證具有相關聯的私密金鑰,請使用 setClientKey 來設定私密金鑰。 如果此金鑰需要密碼,請使用 setClientKeyPassword 來設定私密金鑰的密碼。

使用 ActiveDirectoryServicePrincipalCertificate 驗證模式的範例:

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import com.microsoft.sqlserver.jdbc.SQLServerDataSource;

public class MSEntraServicePrincipalCertificate {
    public static void main(String[] args) throws Exception{
        String principalId = "<service_principal_guid>"; // Replace with your Microsoft Entra service principal ID.
        String clientCertificate = "..."; // Replace with the location of your service principal certificate.

        SQLServerDataSource ds = new SQLServerDataSource();
        ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name
        ds.setDatabaseName("demo"); // Replace with your database
        ds.setAuthentication("ActiveDirectoryServicePrincipalCertificate");
        ds.setUser(principalId); // setAADSecurePrincipalId for JDBC Driver 9.4 and below
        ds.setClientCertificate(clientCertificate);

        try (Connection connection = ds.getConnection();
             Statement stmt = connection.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
            if (rs.next()) {
                System.out.println("You have successfully logged on as: " + rs.getString(1));
            }
        }
    }
}

如果已建立連線,您應該會看到下列訊息作為輸出:

You have successfully logged on as: <your app/client ID>

使用存取權杖來連線

應用程式/服務可以從 Microsoft Entra ID 擷取存取權杖,並用來連線到 Azure SQL 資料庫、Azure SQL 受控執行個體及 Azure Synapse Analytics。

注意

accessToken 只能使用 DriverManager 類別中 getConnection() 方法的 Properties 參數來設定。 不能用於連接字串中。 從驅動程式 12.2 版開始,使用者可以實作並提供 accessToken 回呼給驅動程式,以在連線共用案例中更新權杖。 連線共用案例需要實作連線集區,才能使用標準的 JDBC 連線共用類別

下列範例包含簡單的 Java 應用程式,其可使用存取權杖型驗證來連線到 Azure。

若要建置並執行範例:

  1. 針對您的服務,在 Microsoft Entra ID 中建立應用程式帳戶。

    1. 登入 Azure 入口網站。
    2. 前往左側導覽中的 Microsoft Entra ID
    3. 選取 應用程式註冊
    4. 選取新增註冊
    5. 輸入 mytokentest 作為應用程式的自訂名稱。
    6. 針對可使用應用程式的受支援帳戶類型保留預設選取範圍。
    7. 選取底部的註冊
    8. 無需登入網址。 提供任何項目:https://mytokentest
    9. 選取底部的 Create
    10. 在選取 [註冊] 時,系統會立即建立應用程式,並帶您前往其資源頁面。
    11. 基本方塊中,尋找應用程式 (用戶端) 識別碼並進行複製。 您稍後將會使用此值來設定您的應用程式。
    12. 從瀏覽窗格選取認證及密碼。 在用戶端密碼 (0)索引標籤,選取新增用戶端密碼。 輸入密碼的描述,然後選取到期日 (使用預設值即可)。 選取底部的新增重要事項:離開此頁面之前,請務必拷貝用戶端密碼所產生的。 離開頁面後即無法檢視此值。 此值便是用戶端密碼。
    13. 返回 Microsoft Entra ID 的 [應用程式註冊] 窗格,並尋找 [端點] 索引標籤。複製 OAuth 2.0 token endpoint 下方的網址。 此網址即為您的 STS 網址。

    Azure 入口網站應用程式註冊端點 - STS URL

  2. 以 Microsoft Entra 管理員身分連線至資料庫,並使用 T-SQL 命令為應用程式主體佈建自主資料庫使用者。 如需如何建立 Microsoft Entra 管理員和自主資料庫使用者的詳細資訊,請參閱使用 Microsoft Entra 驗證連線

    CREATE USER [mytokentest] FROM EXTERNAL PROVIDER
    
  3. 在您執行範例的用戶端機器上,下載適用於 Java 程式庫的 Microsoft 驗證程式庫 (MSAL) 及其相依性。 只有要執行這個特定範例時才需要 MSAL。 此範例使用此程式庫中的 API,從 Microsoft Entra ID 擷取存取權杖。 如果您已經有存取權杖,則可以略過此步驟,並移除範例中會擷取存取權杖的區段。

在下列範例中,將 STS URL、用戶端識別碼、用戶端密碼、伺服器和資料庫名稱取代為您的值。

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;

// The microsoft-authentication-library-for-java is needed to retrieve the access token in this example.
import com.microsoft.aad.msal4j.ClientCredentialFactory;
import com.microsoft.aad.msal4j.ClientCredentialParameters;
import com.microsoft.aad.msal4j.ConfidentialClientApplication;
import com.microsoft.aad.msal4j.IAuthenticationResult;
import com.microsoft.aad.msal4j.IClientCredential;

public class MSEntraTokenBased {

    public static void main(String[] args) throws Exception {

        // Retrieve the access token from Microsoft Entra ID.
        String spn = "https://database.windows.net/";
        String stsurl = "https://login.microsoftonline.com/..."; // Replace with your STS URL.
        String clientId = "<service_principal_guid>"; // Replace with your client ID.
        String clientSecret = "..."; // Replace with your client secret.

        String scope = spn +  "/.default";
        Set<String> scopes = new HashSet<>();
        scopes.add(scope);

        ExecutorService executorService = Executors.newSingleThreadExecutor();
        IClientCredential credential = ClientCredentialFactory.createFromSecret(clientSecret);
        ConfidentialClientApplication clientApplication = ConfidentialClientApplication
            .builder(clientId, credential).executorService(executorService).authority(stsurl).build();
        CompletableFuture<IAuthenticationResult> future = clientApplication
            .acquireToken(ClientCredentialParameters.builder(scopes).build());

        IAuthenticationResult authenticationResult = future.get();
        String accessToken = authenticationResult.accessToken();

        System.out.println("Access Token: " + accessToken);

        // Connect with the access token.
        SQLServerDataSource ds = new SQLServerDataSource();

        ds.setServerName("msentra-managed-demo.database.windows.net"); // Replace with your server name.
        ds.setDatabaseName("demo"); // Replace with your database name.
        ds.setAccessToken(accessToken);

        try (Connection connection = ds.getConnection();
                Statement stmt = connection.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
            if (rs.next()) {
                System.out.println("You have successfully logged on as: " + rs.getString(1));
            }
        }
    }
}

如果連線已成功建立,您應該會看到下列訊息作為輸出:

Access Token: <your access token>
You have successfully logged on as: <your client ID>

使用存取權杖回呼來連線

和存取權杖屬性一樣,存取權杖回呼可讓您註冊某個方法以向驅動程式提供存取權杖。 透過屬性來使用這個回呼的優點是,回呼可讓驅動程式在權杖過期時要求新的存取權杖。 例如,建立新連線的關係集區可以要求具有新期間屆滿日的新權杖。 如需詳細資訊,請參閱使用連線共用

下列範例示範如何實作和設定 accessToken 回呼。

import com.microsoft.aad.msal4j.IClientCredential;
import com.microsoft.aad.msal4j.ClientCredentialFactory;
import com.microsoft.aad.msal4j.ConfidentialClientApplication;
import com.microsoft.aad.msal4j.IAuthenticationResult;
import com.microsoft.aad.msal4j.ClientCredentialParameters;
import java.sql.Connection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MSEntraAccessTokenCallback {

    public static void main(String[] args) {

        SQLServerAccessTokenCallback callback = new SQLServerAccessTokenCallback() {
            @Override
            public SqlAuthenticationToken getAccessToken(String spn, String stsurl) {

                String clientSecret = "..."; // Replace with your client secret.
                String clientId = "<service_principal_guid>"; // Replace with your client ID.

                String scope = spn + "/.default";
                Set<String> scopes = new HashSet<>();
                scopes.add(scope);

                try {
                    ExecutorService executorService = Executors.newSingleThreadExecutor();
                    IClientCredential credential = ClientCredentialFactory.createFromSecret(clientSecret);
                    ConfidentialClientApplication clientApplication = ConfidentialClientApplication
                            .builder(clientId, credential).executorService(executorService).authority(stsurl).build();
                    CompletableFuture<IAuthenticationResult> future = clientApplication
                            .acquireToken(ClientCredentialParameters.builder(scopes).build());

                    IAuthenticationResult authenticationResult = future.get();
                    String accessToken = authenticationResult.accessToken();

                    return new SqlAuthenticationToken(accessToken, authenticationResult.expiresOnDate().getTime());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
        };

        SQLServerDataSource ds = new SQLServerDataSource();
        ds.setServerName("msentra-managed-demo.database.windows.net"); // Replaces with your server name.
        ds.setDatabaseName("demo"); // Replace with your database name.
        ds.setAccessTokenCallback(callback);

        try (Connection connection = ds.getConnection();
                Statement stmt = connection.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
            if (rs.next()) {
                System.out.println("You have successfully logged on as: " + rs.getString(1));
            }
        }
    }
}

如果連線已成功建立,您應該會看到下列訊息作為輸出:

You have successfully logged on as: <your client ID>

從 12.4 版開始,可以透過 accessTokenCallbackClass 連接字串屬性來設定 accessToken 回呼。 下列範例將示範如何使用這個屬性來設定 accessToken 回呼。

import com.microsoft.aad.msal4j.IClientCredential;
import com.microsoft.aad.msal4j.ClientCredentialFactory;
import com.microsoft.aad.msal4j.ConfidentialClientApplication;
import com.microsoft.aad.msal4j.IAuthenticationResult;
import com.microsoft.aad.msal4j.ClientCredentialParameters;
import java.sql.Connection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

 

public class MSEntraAccessTokenCallbackClass {
    public static class AccessTokenCallbackClass implements SQLServerAccessTokenCallback {
        @Override
        public SqlAuthenticationToken getAccessToken(String spn, String stsurl) {
            String clientSecret = "..."; // Replace with your client secret.
            String clientId = "<service_principal_guid>"; // Replace with your client ID.
            
            String scope = spn + "/.default";
            Set<String> scopes = new HashSet<>();
            scopes.add(scope);
            
            try {
                ExecutorService executorService = Executors.newSingleThreadExecutor();
                IClientCredential credential = ClientCredentialFactory.createFromSecret(clientSecret);
                ConfidentialClientApplication clientApplication = ConfidentialClientApplication

                        .builder(clientId, credential).executorService(executorService).authority(stsurl).build();
                
                CompletableFuture<IAuthenticationResult> future = clientApplication
                        .acquireToken(ClientCredentialParameters.builder(scopes).build());
                
                IAuthenticationResult authenticationResult = future.get();
                String accessToken = authenticationResult.accessToken();
                
                return new SqlAuthenticationToken(accessToken, authenticationResult.expiresOnDate().getTime());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    
    public static void main(String[] args) throws Exception {
        
        SQLServerDataSource ds = new SQLServerDataSource();
        ds.setServerName("msentra-managed-demo.database.windows.net"); // Replaces with your server name.
        ds.setDatabaseName("demo"); // Replace with your database name.
        ds.setAccessTokenCallbackClass(AccessTokenCallbackClass.class.getName());
        
        try (Connection connection = ds.getConnection();
             Statement stmt = connection.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT SUSER_SNAME()")) {
            if (rs.next()) {
                System.out.println("You have successfully logged on as: " + rs.getString(1));
            }
        }
    }
}

如果連線已成功建立,您應該會看到下列訊息作為輸出:

You have successfully logged on as: <your client ID>

後續步驟

在下列文章中深入了解相關概念: