共用方式為


從內部部署的 Go 應用程式對 Azure 資源進行驗證

裝載於 Azure 外部的應用程式(例如內部部署或第三方資料中心)應該使用應用程式服務主體在存取 Azure 資源時向 Azure 進行驗證。 應用程式服務主體物件是使用 Azure 中的應用程式註冊程式所建立。 建立應用程式服務主體時,將會為您的應用程式產生用戶端標識碼和客戶端密碼。 接著,用戶端標識碼、用戶端密碼和租使用者標識符會儲存在環境變數中,讓 Azure SDK for Go 在運行時間向 Azure 驗證您的應用程式。

應該為每個裝載應用程式的環境建立不同的應用程式註冊。 這可讓每個服務主體設定環境特定的資源許可權,並確保部署到某個環境的應用程式不會與屬於另一個環境一部分的 Azure 資源交談。

1 - 在 Azure 中註冊應用程式

您可以使用 Azure 入口網站或 Azure CLI 向 Azure 註冊應用程式。

az ad sp create-for-rbac --name <app-name>

命令的輸出會類似下列內容。 請記下這些值,或讓此視窗保持開啟,因為您在後續步驟中需要這些值,而且無法再次檢視密碼 (客戶端密碼) 值。

{
  "appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
  "displayName": "msdocs-python-sdk-auth-prod",
  "password": "Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6",
  "tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
}

2 - 將角色指派給應用程式服務主體

接下來,您必須判斷您的應用程式需要哪些角色(許可權),以取得哪些資源,並將這些角色指派給您的應用程式。 可以在資源、資源群組或訂用帳戶範圍指派角色。 此範例示範如何在資源群組範圍指派服務主體的角色,因為大部分的應用程式都會將其所有 Azure 資源分組到單一資源群組中。

服務主體會使用 az role assignment create 命令在 Azure 中分配角色。

az role assignment create --assignee {appId} \
    --scope /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName} \
    --role "{roleName}" 

若要取得服務主體可指派的角色名稱,請使用 az role definition list 命令。

az role definition list \
    --query "sort_by([].{roleName:roleName, description:description}, &roleName)" \
    --output table

例如,若要允許具有 00001111-aaaa-2222-bbbb-3333cccc4444 讀取、寫入和刪除 azure 記憶體 Blob 容器和數據之 appId 的服務主體,以及 msdocs-go-sdk-auth-example 訂用帳戶中標識符為 aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e的資源群組,您可以使用下列命令,將應用程式服務主體指派給 儲存器 Blob 數據參與者 角色。

az role assignment create --assignee 00001111-aaaa-2222-bbbb-3333cccc4444 \
    --scope /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-go-sdk-auth-example \
    --role "Storage Blob Data Contributor"

如需使用 Azure CLI 在資源或訂用帳戶層級指派許可權的相關信息,請參閱 使用 Azure CLI指派 Azure 角色一文。

3 - 設定應用程式的環境變數

您必須為執行 Go 應用程式的程式設定 AZURE_CLIENT_IDAZURE_TENANT_IDAZURE_CLIENT_SECRET 環境變數,讓應用程式服務主體認證可在運行時間使用。 DefaultAzureCredential 對象會尋找這些環境變數中的服務主體資訊。

變數名稱 價值
AZURE_CLIENT_ID Azure 服務主體的應用程式標識碼
AZURE_TENANT_ID 應用程式 Microsoft Entra 租用戶的 ID
AZURE_CLIENT_SECRET Azure 服務主體的密碼
export AZURE_TENANT_ID="<active_directory_tenant_id>"
export AZURE_CLIENT_ID="<service_principal_appid>"
export AZURE_CLIENT_SECRET="<service_principal_password>"

4 - 在應用程式中實作 DefaultAzureCredential

若要向 Azure 驗證 Azure SDK 用戶端物件,您的應用程式應該使用來自 azidentity 套件的 DefaultAzureCredential 類型。

首先,將 azidentity 套件新增至您的應用程式。

go get github.com/Azure/azure-sdk-for-go/sdk/azidentity

接下來,針對在應用程式中具現化 Azure SDK 用戶端的任何 Go 程式代碼,您會想要:

  1. 匯入 azidentity 套件。
  2. 建立 DefaultAzureCredential 類型的實例。
  3. DefaultAzureCredential 類型的實例傳遞至 Azure SDK 用戶端建構函式。

下列程式代碼區段會顯示此範例。

import (
	"context"

	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

const (
	account       = "https://<replace_with_your_storage_account_name>.blob.core.windows.net/"
	containerName = "sample-container"
	blobName      = "sample-blob"
	sampleFile    = "path/to/sample/file"
)

func main() {
    // create a credential
    cred, err := azidentity.NewDefaultAzureCredential(nil)
    if err != nil {
      // TODO: handle error
    }
    
    // create a client for the specified storage account
    client, err := azblob.NewClient(account, cred, nil)
    if err != nil {
      // TODO: handle error
    }
    
    // TODO: perform some action with the azblob Client
    // _, err = client.DownloadFile(context.TODO(), <containerName>, <blobName>, <target_file>, <DownloadFileOptions>)
}

當上述程式代碼具現化 DefaultAzureCredential時,DefaultAzureCredential 讀取環境變數 AZURE_TENANT_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRET,讓應用程式服務主體資訊連線到 Azure。