使用 go-mssqldb 的 Microsoft Entra ID 驗證

驅動程式go-mssqldb支援透過azuread套件進行 Microsoft Entra ID 認證。 此套件會註冊一個名為 azuresql 的個別驅動程式,該驅動程式會封裝標準的 sqlserver 驅動程式,並提供 Microsoft Entra ID 憑證支援。

警告

所有內建的 fedauth 驗證方法都需要使用 azuresql 驅動程式名稱(而不是 sqlserver)。 如果您將 sql.Open("sqlserver", ...)fedauth 參數一起使用,驗證會在 Login failed for user '' 下無聲地失敗。 匯入套件 azuread 並依以下範例使用 azuresql

選擇 FedAuth 驗證流程

請使用以下表格為您的主機環境及憑證來源選擇合適的流程:

如果你需要從……連線 從……開始 使用時機...
地方發展 ActiveDirectoryDefault 你想重用 Azure CLI 或 Azure Developer 的 CLI 憑證,但不要在本地設定服務主體或管理身份。
一個由 Azure 託管的應用程式,具有受管理身份 ActiveDirectoryManagedIdentity 你想要一個可預測的生產設定,且不希望鏈中有其他本地憑證來源。
Azure DevOps 中的 CI/CD 管線 ActiveDirectoryAzurePipelines 您的管線已經使用 Azure 服務連線,並公開 SYSTEM_ACCESSTOKEN
Kubernetes 搭配 Azure 工作負載身分識別 ActiveDirectoryWorkloadIdentity 你的 pod 會收到一個 OIDC 令牌檔案,你想要的是工作負載身份,而不是客戶端秘密。
擁有秘密或憑證的服務主體 ActiveDirectoryServicePrincipal 你的應用程式以應用程式註冊身份認證,你則管理客戶端秘密或憑證。
一個已經有存取令牌的工具 ActiveDirectoryServicePrincipalAccessToken 或自訂 代幣提供者 你的應用程式會收集並刷新驅動程式外的代幣。
來自上游網頁 API 的委派使用者憑證 ActiveDirectoryOnBehalfOf 你需要在中介層服務中,將使用者權杖交換為 SQL 範圍權杖。
開發者工具或互動工具 ActiveDirectoryInteractiveActiveDirectoryDeviceCodeActiveDirectoryAzCliActiveDirectoryAzureDeveloperCli 有人在場才能登入,或者你想重用現有的本地 CLI 會話。
一個僅支援 Windows 的應用程式,能處理整合驗證需求 ActiveDirectoryIntegrated (進階) 你為整合情境提供自訂的代幣獲取邏輯。

如果你在本機開發環境和 Azure 託管環境之間共用同一個連線字串,ActiveDirectoryDefault 是一個不錯的起點。 在生產環境中,使用 ActiveDirectoryManagedIdentityActiveDirectoryServicePrincipal 避免憑證鏈延遲。

安裝 azuread 套件

下載 azuread 子套件,該子套件會註冊驅動程式 azuresql

go get github.com/microsoft/go-mssqldb/azuread

使用 azuresql 驅動程式

匯入 azuread 套件(取代或附加於基礎 go-mssqldb 套件),並使用 azuresql 驅動程式名稱開啟連線:

import (
    "database/sql"

    _ "github.com/microsoft/go-mssqldb/azuread"
)

func main() {
    db, err := sql.Open("azuresql",
        "sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryDefault&encrypt=true&TrustServerCertificate=false")
    // ...
}

以下所有範例都針對 Azure SQL。 保留 encrypt=true&TrustServerCertificate=false 連接字串 這個字串,讓驅動程式驗證伺服器憑證。

Fedauth 憑證類型

將連線參數設 fedauth 為以下其中一個值。 大多數類型都對應到來自 azidentity 套件的 Azure Identity 認證。 ActiveDirectoryServicePrincipalAccessToken 而自訂的權杖提供者 API 則使用呼叫者提供的權杖。

ActiveDirectoryDefault

使用 azidentity.DefaultAzureCredential,依序嘗試以下憑證來源:

  1. 環境變數(AZURE_TENANT_IDAZURE_CLIENT_ID,等等)。
  2. Kubernetes 的工作負載身分。
  3. 管理式身分
  4. Azure CLI 認證
  5. Azure Developer CLI 認證。
sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryDefault&encrypt=true&TrustServerCertificate=false

本地開發時使用這種類型,因為它會自動擷取 Azure CLI 憑證。 在正式環境中,請直接使用 ActiveDirectoryManagedIdentityActiveDirectoryServicePrincipalDefaultAzureCredential 在第一次連線時會逐一通過每個憑證來源,這會增加生產工作負載不需要的延遲。

ActiveDirectoryManagedIdentity

透過系統指派或使用者指派的管理身份進行驗證。 對於使用者指派的身份,請在參數 user id 中提供客戶端 ID:

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryManagedIdentity&encrypt=true&TrustServerCertificate=false

使用使用者指派的身份:

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryManagedIdentity&user id=<client-id>&encrypt=true&TrustServerCertificate=false

Note

ActiveDirectoryMSIActiveDirectoryManagedIdentity 的別名。

ActiveDirectoryServicePrincipal

使用用戶端 ID 和用戶端密碼,以服務主體(應用程式註冊)進行驗證:

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryServicePrincipal&user id=<client-id>&password=<client-secret>&encrypt=true&TrustServerCertificate=false

對於基於憑證的服務主體認證,請與 clientcertpath=<path-to-certificate>password=<certificate-password>一起使用。

Note

ActiveDirectoryApplicationActiveDirectoryServicePrincipal 的別名。

ActiveDirectoryServicePrincipalAccessToken

使用應用程式直接在連線字串中傳遞的預先取得服務主體存取權杖:

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryServicePrincipalAccessToken&password=<access-token>&encrypt=true&TrustServerCertificate=false

只有當你的應用程式已經在驅動程式外取得並刷新存取權杖時,才使用這個流程。 對於大多數服務對服務的情境,應優先使用 ActiveDirectoryServicePrincipal 或自訂權杖提供者。

ActiveDirectoryPassword

Important

ActiveDirectoryPassword 驗證選項(Microsoft Entra ID 密碼驗證)在 Microsoft SQL 驅動程式中已被棄用。 這種高風險的認證流程與強制的 Microsoft Entra 多重驗證(MFA)不相容,且在強制執行多重驗證的租戶中可能無法運作。 計劃遷移到不同的 Microsoft Entra 認證方式。

Microsoft Entra ID 的密碼驗證基於 OAuth 2.0 資源擁有者密碼憑證(ROPC)授權,允許應用程式直接處理使用者的密碼來登入。

Microsoft 建議不要使用 ROPC 流程,因為它與多重認證(MFA)不相容。 在大部分情況下,有更安全的替代方案可供使用,並建議使用。 這種流程需要對應用程式高度信任,且存在其他流程中不存在的風險。 只有在無法用更安全的流程時才使用這個流程。 Microsoft 正逐步放棄這種高風險的認證流程,以保護使用者免受惡意攻擊。 欲了解更多資訊,請參閱 Azure 強制多重驗證的規劃

當使用者在登入時,請使用 ActiveDirectoryInteractive 或 ActiveDirectoryIntegrated 認證,使登入使用者的稽核憑證及條件存取政策得以適用。

對於服務對服務的無人值守情境,請遵循 Microsoft Entra 服務帳戶指導方針

  • 如果你的應用程式是在 Azure 基礎設施上執行,請使用 ActiveDirectoryMSI(或某些驅動程式中的 ActiveDirectoryManagedIdentity)。 受管理身份消除了維護與輪替秘密與憑證的負擔。
  • 如果無法使用受管理身份(例如應用程式在 Azure 外執行),則使用 ActiveDirectoryServicePrincipal。 在驅動程式支援時,偏好使用用戶端憑證而非用戶端秘密。 使用憑證時,私鑰會留在用戶端,只有簽署的斷言會送給 Microsoft Entra 以驗證客戶端。 如果金鑰儲存在硬體(如 TPM 或 HSM)或標記為不可匯出,就無法像用戶端秘密那樣以字串形式複製。
  • 不要把 Microsoft Entra 使用者帳號當作服務帳號使用。

使用 Microsoft Entra 使用者名稱和密碼進行驗證:

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryPassword&user id=<user>@mydomain.com&password=<password>&applicationclientid=<app-id>&encrypt=true&TrustServerCertificate=false

applicationclientid 參數是此流程所必需的。

ActiveDirectoryInteractive

為使用者開啟基於瀏覽器的互動式登入提示。 適合本地開發工具:

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryInteractive&user id=<user>@mydomain.com&applicationclientid=<app-id>&encrypt=true&TrustServerCertificate=false

applicationclientid 參數是此流程所必需的。

ActiveDirectoryDeviceCode

顯示裝置代碼供使用者在 https://microsoft.com/devicelogin 輸入。 適用於沒有瀏覽器的環境:

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryDeviceCode&encrypt=true&TrustServerCertificate=false

ActiveDirectoryAzCli

使用登入的 Azure CLI 會話中的令牌:

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryAzCli&encrypt=true&TrustServerCertificate=false

ActiveDirectoryAzureDeveloperCli

使用已登入的 Azure Developer CLI(azd)工作階段中的權杖:

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryAzureDeveloperCli&encrypt=true&TrustServerCertificate=false

Active Directory 環境

從環境變數讀取憑證。 Azure 身份函式庫會檢查變數如 AZURE_TENANT_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRET和 :

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryEnvironment&encrypt=true&TrustServerCertificate=false

Active Directory 工作負載身分識別

透過工作負載身分聯合進行驗證。 在設定 Azure Workload Identity 的 Kubernetes Pods 中使用此方法。

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryWorkloadIdentity&encrypt=true&TrustServerCertificate=false

ActiveDirectoryAzurePipelines

透過使用 Azure Pipelines 服務連線來認證。 可以在 連接字串 中提供 pipeline 參數,或讓驅動程式讀取 Azure Pipelines 環境變數的缺失值。

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryAzurePipelines&user id=<client-id>@<tenant-id>&serviceconnectionid=<service-connection-id>&systemtoken=<system-access-token>&encrypt=true&TrustServerCertificate=false

依驅動程式需求設定參數:

參數 說明
user id 服務主體用戶端識別碼,後面可選擇加上 @tenant-id
serviceconnectionid 來自 Azure DevOps 的服務連線 ID。
systemtoken 管道系統存取權杖($(System.AccessToken))。

ActiveDirectoryClientAssertion

透過使用用戶端斷言(簽署的 JWT 標記)來驗證,而非用戶端秘密。 在參數 clientassertion 中提供有符號的 JWT:

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryClientAssertion&user id=<client-id>@<tenant-id>&clientassertion=<jwt-token>&encrypt=true&TrustServerCertificate=false

ActiveDirectoryOnBehalfOf

使用 On-Behalf-Of(OBO)流程進行驗證。 驅動程式會將上游使用者令牌交換為一個針對 SQL Server 的新令牌。

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryOnBehalfOf&user id=<client-id>@<tenant-id>&password=<client-secret>&userassertion=<user-token>&encrypt=true&TrustServerCertificate=false

用戶端驗證階段可使用 passwordclientcertpathclientassertion,但 userassertion 則一定需要。

Active Directory 整合式

支援進階的整合驗證工作流程。 此模式需要透過代幣提供者進行自訂的憑證獲取邏輯。

此模式僅在 Windows 上使用。 在 Linux 和 macOS 上,請使用自訂的憑證提供者來進行認證流程。

sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryIntegrated&encrypt=true&TrustServerCertificate=false

自訂代幣提供者

如果內建 fedauth 類型都不符合你的情境,請使用以下代幣提供者 API 之一來提供你自己的代幣獲取邏輯:

當你有預先取得的 OAuth2 存取權杖時,請使用此 API:

import (
    "context"
    "database/sql"
    "log"

    "github.com/microsoft/go-mssqldb"
)

connector, err := mssql.NewSecurityTokenConnector(
    "sqlserver://<server>.database.windows.net?database=AdventureWorks2025&encrypt=true&TrustServerCertificate=false",
    func(ctx context.Context) (string, error) {
        // Return a pre-acquired OAuth2 access token.
        return myTokenProvider(ctx)
    },
)
if err != nil {
    log.Fatal(err)
}
db := sql.OpenDB(connector)

NewAccessTokenConnector(簡化API)

使用此 API 進行更簡單的代幣取得,無需上下文處理。

import (
    "database/sql"
    "log"

    "github.com/microsoft/go-mssqldb"
)

connector, err := mssql.NewAccessTokenConnector(
    "sqlserver://<server>.database.windows.net?database=AdventureWorks2025&encrypt=true&TrustServerCertificate=false",
    func() (string, error) {
        // Return a pre-acquired OAuth2 access token.
        return mySimpleTokenProvider()
    },
)
if err != nil {
    log.Fatal(err)
}
db := sql.OpenDB(connector)

NewActiveDirectoryTokenConnector(自訂 ADAL 工作流程)

當內建模式和 SecurityToken API 都不fedauth適合你的情境時,請使用此 API 進行自訂的 Azure AD 憑證取得工作流程:

import (
    "context"
    "database/sql"
    "log"

    "github.com/microsoft/go-mssqldb"
)

connector, err := mssql.NewActiveDirectoryTokenConnector(
    "sqlserver://<server>.database.windows.net?database=AdventureWorks2025&encrypt=true&TrustServerCertificate=false",
    mssql.FedAuthADALWorkflowPassword,
    func(ctx context.Context, serverSPN, stsURL string) (string, error) {
        // Custom ADAL workflow using server-provided SPN and STS URL.
        return myCustomADALFlow(ctx, serverSPN, stsURL)
    },
)
if err != nil {
    log.Fatal(err)
}
db := sql.OpenDB(connector)

當你需要整合自訂身份提供者、實作權杖快取,或處理套件未涵蓋 azuread 的憑證類型時,這種方法非常有用。 大多數應用程式應該使用 NewSecurityTokenConnector 預先取得的代幣。

常見的證照選項

以下參數適用於多種 fedauth 類型:

參數 說明
applicationclientid 客戶端應用程式ID。 ActiveDirectoryPasswordActiveDirectoryInteractive 需要此項。
clientcertpath 用於以憑證為基礎的服務主體或 On-Behalf-Of 驗證的 PEM 或 PFX 用戶端憑證檔案路徑。
clientassertion 簽署 JWT 聲明,用於 ActiveDirectoryClientAssertion 或 On-Behalf-Of 認證。
serviceconnectionid Azure Pipelines 服務連線識別碼。
systemtoken Azure Pipelines 系統存取權杖
userassertion ActiveDirectoryOnBehalfOf 的上游用戶代幣。
tokenfilepath 通往 Kubernetes 中 OIDC ActiveDirectoryWorkloadIdentity 令牌檔案的路徑。
additionallyallowedtenants 逗號分隔的額外租戶 ID 清單,供多租戶認證時允許。
disableinstancediscovery 設為 true 以停用實例發現;僅在你控制權威 URL 時使用。
sendcertificatechain 設定為 true 以傳送憑證鏈以進行基於憑證的認證。