分享方式:


教學課程:建立函數應用程式,其會使用身分識別而不是秘密連線到 Azure 服務

本教學課程說明如何儘可能使用 Microsoft Entra 身分識別而不是秘密或連接字串,來設定函數應用程式。 使用身分識別可協助您避免意外洩漏敏感性秘密,並更清楚地了解資料存取方式。 若要深入了解身分識別型連線,請參閱設定身分識別型連線

雖然顯示的程序通常適用於所有語言,但本教學課程目前專門用來支援 Windows 上的 C# 類別庫函數。

在本教學課程中,您會了解如何:

  • 使用 ARM 範本在 Azure 中建立函數應用程式
  • 在函數應用程式上同時啟用系統指派和使用者指派的受控識別
  • 建立授與其他資源權限的角色指派
  • 將無法取代為身分識別的秘密移至 Azure Key Vault
  • 設定應用程式以使用其受控識別連線到預設主機儲存體

在完成本教學課程之後,您應該完成後續教學課程,其會說明如何將身分識別型連線 (而非密碼) 與觸發程序和繫結搭配使用

必要條件

為何使用身分識別?

管理秘密和認證是各種規模的小組面臨的共同挑戰。 秘密必須受到保護,以防範遭人竊取或意外洩漏,而且您可能需要定期輪換這些秘密。 許多 Azure 服務可讓您改用 Microsoft Entra ID 中的身分識別來驗證用戶端,並檢查可快速修改和撤銷的權限。 這可讓您更大地控制應用程式安全性,並降低作業額外負荷。 身分識別可能是人類使用者 (例如應用程式的開發人員),或是 Azure 中具有受控識別的執行中應用程式。

有些服務不支援 Microsoft Entra 驗證,因此您的應用程式仍可能需要秘密。 不過,這些秘密可以儲存在 Azure Key Vault 中,這有助於簡化秘密的管理生命週期。 存取金鑰保存庫也是使用身分識別加以控制。

藉由了解如何在可能時使用身分識別而不是秘密,以及在不能時使用金鑰保存庫,您將能夠降低風險、減少作業額外負荷,以及通常改善應用程式的安全性態勢。

建立函數應用程式,針對必要的秘密使用金鑰保存庫

Azure 檔案儲存體是尚未支援 SMB 檔案共用進行 Microsoft Entra 驗證的服務範例。 Azure 檔案儲存體是進階方案和取用方案上 Windows 部署的預設檔案系統。 雖然我們可以完全移除 Azure 檔案儲存體,但這會引入您可能不想要的限制。 相反地,您會將 Azure 檔案儲存體連接字串移至 Azure Key Vault。 如此一來,其會集中管理,而存取受到身分識別控制。

建立 Azure Key Vault

首先,您需要金鑰保存庫來儲存秘密。 您會將其設定為使用 Azure 角色型存取控制 (RBAC),以決定誰可以從保存庫讀取秘密。

  1. Azure 入口網站中,選擇 [建立資源 (+)]。

  2. 在 [建立資源] 頁面上,選取 [安全性]>[金鑰保存庫]

  3. 在 [基本] 頁面上,使用下表來設定金鑰保存庫。

    選項 建議的值 描述
    訂用帳戶 您的訂用帳戶 在其下建立這個新函數應用程式的訂用帳戶。
    資源群組 myResourceGroup 將在其中建立函數應用程式的新資源群組名稱。
    金鑰保存庫名稱 全域唯一的名稱 識別新金鑰保存庫的名稱。 保存庫名稱只能包含英數字元和虛線,且不得以數字開頭。
    定價層 標準 計費選項。 對於本教學課程,標準就足夠了。
    區域 慣用區域 選擇的區域應靠近您或靠近函式將會存取的其他服務。

    針對 [復原選項] 區段使用預設選取項目。

  4. 記下您所使用的名稱,因為稍後會需要此名稱。

  5. 按 [下一步: 存取原則] 以瀏覽至 [存取原則] 索引標籤。

  6. 在 [權限模型] 下,選擇 [Azure 角色型存取控制]

  7. 選取 [檢閱 + 建立]。 檢閱設定,然後按一下 [建立]

設定應用程式的身分識別和權限

若要使用 Azure Key Vault,您的應用程式必須具有可獲授與讀取秘密權限的身分識別。 此應用程式會使用一個使用者指派的身分識別,以便甚至在建立應用程式之前設定權限。 您可以在如何在 Azure Functions 中使用受控識別主題中深入了解適用於 Azure Functions 的受控識別。

  1. Azure 入口網站中,選擇 [建立資源 (+)]。

  2. 在 [建立資源] 頁面上,選取 [身分識別]>[使用者指派的受控識別]

  3. 在 [基本] 頁面上,使用下表來設定身分識別。

    選項 建議的值 描述
    訂用帳戶 您的訂用帳戶 在其下建立這個新函數應用程式的訂用帳戶。
    資源群組 myResourceGroup 將在其中建立函數應用程式的新資源群組名稱。
    區域 慣用區域 選擇的區域應靠近您或靠近函式將會存取的其他服務。
    名稱 全域唯一的名稱 識別新使用者指派身分識別的名稱。
  4. 選取 [檢閱 + 建立]。 檢閱設定,然後按一下 [建立]

  5. 建立身分識別後,請在入口網站中瀏覽至該身分識別。 選取 [屬性],並記下 [資源識別碼],因為稍後需要該識別碼。

  6. 選取 [Azure 角色指派],然後按一下 [新增角色指派 (預覽)]

  7. 在 [新增角色指派 (預覽)] 頁面中,使用下表所示的選項。

    選項 建議的值 描述
    範圍 Key Vault 範圍是角色指派套用至其中的一組資源。 範圍在較低層級繼承的層級。 例如,如果您選取訂用帳戶範圍,則角色指派會套用至訂用帳戶中的所有資源群組和資源。
    訂用帳戶 您的訂用帳戶 在其下建立這個新函數應用程式的訂用帳戶。
    資源 您的金鑰保存庫 您稍早建立的金鑰保存庫。
    Role Key Vault 祕密使用者 角色是被授與的權限集合。 金鑰保存庫秘密使用者授權身分識別可從保存庫讀取秘密值。
  8. 選取 [儲存]。 當您重新整理身分識別的角色指派清單時,可能需要一或兩分鐘的時間才會顯示角色。

身分識別現在能夠讀取金鑰保存庫中儲存的秘密。 稍後在本教學課程中,您將針對不同的用途新增其他角色指派。

產生用於建立函數應用程式的範本

建立函數應用程式的入口網站體驗不會與 Azure Key Vault 互動,因此您必須產生和編輯 Azure Resource Manager 範本。 然後,您可以使用此範本建立函數應用程式,從金鑰保存庫參考 Azure 檔案儲存體連接字串。

重要

在您編輯 ARM 範本之前,請不要建立函數應用程式。 必須在建立應用程式時設定 Azure 檔案儲存體設定。

  1. Azure 入口網站中,選擇 [建立資源 (+)]。

  2. 在 [建立資源] 頁面上,選取[計算]>[函數應用程式]

  3. 在 [基本] 頁面上,使用下表來設定函數應用程式。

    選項 建議的值 描述
    訂用帳戶 您的訂用帳戶 在其下建立這個新函數應用程式的訂用帳戶。
    資源群組 myResourceGroup 將在其中建立函數應用程式的新資源群組名稱。
    函數應用程式名稱 全域唯一的名稱 用以識別新函式應用程式的名稱。 有效的字元是 a-z (不區分大小寫)、0-9-
    發行 代碼 選擇要發佈程式碼檔案或 Docker 容器。
    執行階段堆疊 .NET 本教學課程使用 .NET。
    區域 慣用區域 選擇的區域應靠近您或靠近函式將會存取的其他服務。
  4. 選取 [檢閱 + 建立]。 您的應用程式會在 [裝載] 和 [監視] 頁面上使用預設值。 歡迎您檢閱預設選項,而這些選項將會包含在您產生的 ARM 範本中。

  5. 選擇 [下載範本進行自動化] (位於 [下一步] 按鈕右側),而不是在這裡建立函數應用程式。

  6. 在範本頁面中,選取 [部署],然後在 [自訂部署] 頁面中,選取 [編輯範本]

    Screenshot of where to find the deploy button at the top of the template screen.

編輯範本

您現在會編輯範本,以將 Azure 檔案儲存體連接字串儲存在金鑰保存庫中,並允許函數應用程式參考該字串。 確定您有先前各節中的下列值,然後再繼續進行:

  • 使用者指派的身分識別資源識別碼
  • 金鑰保存庫的名稱

注意

如果您將建立完整範本進行自動化,您想要包括身分識別和角色指派資源的定義,以及適當的 dependsOn 子句。 這會取代已使用入口網站的稍早步驟。 請參閱 Azure Resource Manager 指引和每個服務的文件。

  1. 在編輯器中,尋找 resources 陣列開始的位置。 在函數應用程式定義之前,新增下列區段,將 Azure 檔案儲存體連接字串放入金鑰保存庫中。 將 "VAULT_NAME" 替換成您的金鑰保存庫名稱。

    {
        "type": "Microsoft.KeyVault/vaults/secrets",
        "apiVersion": "2016-10-01",
        "name": "VAULT_NAME/azurefilesconnectionstring",
        "properties": {
            "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
        },
        "dependsOn": [
            "[concat('Microsoft.Storage/storageAccounts/', parameters('storageAccountName'))]"
        ]
    },
    
  2. 在函數應用程式資源的定義 (已將 type 設定為 Microsoft.Web/sites) 中,將 Microsoft.KeyVault/vaults/VAULT_NAME/secrets/azurefilesconnectionstring 新增至 dependsOn 陣列。 再次將 "VAULT_NAME" 替換成您的金鑰保存庫名稱。 如此一來,就不會在定義該秘密之前建立您的應用程式。 dependsOn 陣列應該看起來如下範例所示。

        {
            "type": "Microsoft.Web/sites",
            "apiVersion": "2018-11-01",
            "name": "[parameters('name')]",
            "location": "[parameters('location')]",
            "tags": null,
            "dependsOn": [
                "microsoft.insights/components/idcxntut",
                "Microsoft.KeyVault/vaults/VAULT_NAME/secrets/azurefilesconnectionstring",
                "[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
                "[concat('Microsoft.Storage/storageAccounts/', parameters('storageAccountName'))]"
            ],
            // ...
        }
    
  3. 將下列範例中的 identity 區塊新增至函數應用程式資源的定義。 將 "IDENTITY_RESOURCE_ID" 替換成使用者指派的身分識別資源識別碼。

    {
        "apiVersion": "2018-11-01",
        "name": "[parameters('name')]",
        "type": "Microsoft.Web/sites",
        "kind": "functionapp",
        "location": "[parameters('location')]",
        "identity": {
            "type": "SystemAssigned,UserAssigned",
            "userAssignedIdentities": {
                "IDENTITY_RESOURCE_ID": {}
            }
        },
        "tags": null,
        // ...
    }
    

    identity 區塊也會設定系統指派的身分識別,您將在本教學課程稍後使用此身分識別。

  4. keyVaultReferenceIdentity 屬性新增至函數應用程式的 properties 物件,如下列範例所示。 將 "IDENTITY_RESOURCE_ID" 替換成使用者指派的身分識別資源識別碼。

    {
        // ...
         "properties": {
                "name": "[parameters('name')]",
                "keyVaultReferenceIdentity": "IDENTITY_RESOURCE_ID",
                // ...
         }
    }
    

    您需要此設定,因為應用程式可能已設定多個使用者指派的身分識別。 每當您想要使用一個使用者指派的身分識別時,都必須透過某個識別碼來指定哪一個。 對於系統指派的身分識別並非如此,因為應用程式只會有一個。 許多使用受控識別的功能都假設其應該預設使用系統指派的受控識別。

  5. 現在尋找定義 WEBSITE_CONTENTAZUREFILECONNECTIONSTRING 應用程式設定的 JSON 物件,其看起來應該如下列範例所示:

    {
        "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
        "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
    },
    
  6. value 欄位取代為秘密的參考,如下列範例所示。 將 "VAULT_NAME" 替換成您的金鑰保存庫名稱。

    {
        "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
        "value": "[concat('@Microsoft.KeyVault(SecretUri=', reference(resourceId('Microsoft.KeyVault/vaults/secrets', 'VAULT_NAME', 'azurefilesconnectionstring')).secretUri, ')')]"
    },
    
  7. 選取 [儲存] 以儲存更新的 ARM 範本。

部署已修改的範本

  1. 確定您建立的選項 (包括 [資源群組]) 仍然正確,然後選取 [檢閱 + 建立]

  2. 在您的範本驗證之後,請記下儲存體帳戶名稱,因為您稍後會使用此帳戶。 最後,選取 [建立] 以建立您的 Azure 資源,並將您的程式碼部署至函數應用程式。

  3. 在部署完成之後,選取 [移至資源群組],然後選取新的函數應用程式。

恭喜! 您已成功建立函數應用程式,從 Azure Key Vault 參考 Azure 檔案儲存體連接字串。

每當您的應用程式需要新增對秘密的參考時,您只需要定義新的應用程式設定,指向金鑰保存庫中儲存的值。 您可以在 Azure Functions 的金鑰保存庫參考中深入了解此情況。

提示

Application Insights 連接字串及其包括的檢測金鑰未被視為秘密,因此可以使用讀者權限從 App Insights 擷取。 您不需要將其移至金鑰保存庫,不過當然可以。

使用 AzureWebJobsStorage 的受控識別

接下來,您將使用您在先前步驟中為 AzureWebJobsStorage 連線設定的系統指派身分識別。 AzureWebJobsStorage 由 Azure Functions 執行階段以及數個觸發程序和繫結用來在多個執行中的執行個體之間進行協調。 您的函數應用程式需要運作,就像 Azure 檔案儲存體一樣,當您建立新的函數應用程式時,預設會使用連接字串進行設定。

將系統指派的身分識別存取權授與儲存體帳戶

與您之前搭配使用者指派的身分識別和金鑰保存庫採取的步驟類似,您現在會建立一個角色指派,將系統指派的身分識別存取權授與儲存體帳戶。

  1. Azure 入口網站中,瀏覽至稍早使用函數應用程式建立的儲存體帳戶。

  2. 選取存取控制 (IAM)。 可以在這裡檢視和設定有權存取資源的人員。

  3. 按一下 [新增],然後選取 [新增角色指派]。

  4. 搜尋儲存體 Blob 資料擁有者、選取該擁有者,然後按 [下一步]

  5. 在 [成員] 索引標籤上的 [指派存取權的對象] 底下,選擇 [受控識別]

  6. 按一下 [選取成員] 以開啟 [選取受控識別] 面板。

  7. 確認 [訂用帳戶] 是您稍早建立資源的訂用帳戶。

  8. [受控識別] 選取器中,從 [系統指派的受控識別] 類別中選擇 [函數應用程式]。 標籤「函數應用程式」旁邊可能有一個以括號括住的數字,指出訂用帳戶中具有系統指派身分識別的應用程式數目。

  9. 您的應用程式應該會出現在輸入欄位下方的清單中。 如果畫面上未顯示,可以使用 [選取] 方塊篩選具有您應用程式名稱的結果。

  10. 按一下您的應用程式。 該應用程式應該會向下移至 [選取的成員] 區段。 按一下 [選取]。

  11. 回到 [新增角色指派] 畫面,按一下 [檢閱 + 指派]。 檢閱組態,然後按一下 [檢閱 + 指派]。

提示

如果想要針對 Blob 觸發的函數使用函數應用程式,您必須透過 AzureWebJobsStorage 所使用的帳戶,針對 儲存體帳戶參與者儲存體佇列資料參與者角色重複這些步驟。 若要深入1 解,請參閱 Blob 觸發程序身分識別型連線

編輯 AzureWebJobsStorage 設定

接下來,您將更新函數應用程式,以在其針對主機儲存體使用 Blob 服務時,使用其系統指派的身分識別。

重要

AzureWebJobsStorage 設定是由某些觸發程序和繫結使用,而且這些延伸模組也必須能夠使用身分識別型連線。 使用 Blob 觸發程序或事件中樞觸發程序的應用程式可能需要更新這些延伸模組。 因為沒有針對此應用程式定義的任何函式,所以還沒有任何問題。 若要深入了解此需求,請參閱使用身分識別連線到主機儲存體

同樣地,在 Linux 使用量中使用伺服器端組建時,AzureWebJobsStorage 會用於部署成品。 在 Linux 使用量中啟用 AzureWebJobsStorage 的身分識別型連線時,您必須透過外部部署套件進行部署。

  1. Azure 入口網站中,瀏覽至您的函式應用程式。

  2. 在 [設定] 底下,選取 [設定]

  3. 選取 AzureWebJobsStorage 應用程式設定旁邊的 [編輯] 按鈕,並根據下列值加以變更。

    選項 建議的值 名描述
    名稱 AzureWebJobsStorage__accountName 將名稱從 AzureWebJobsStorage 更新為確切的名稱 AzureWebJobsStorage__accountName。 此設定會告訴主機使用身分識別,而不是尋找儲存的秘密。 新設定會使用雙底線 (__) ,這是應用程式設定中的特殊字元。
    您的帳戶名稱 將連接字串中的名稱只更新為您的 StorageAccountName

    此設定會讓系統知道其應該使用身分識別來連線到資源。

  4. 選取 [確定],然後選取 [儲存]>[繼續] 以儲存您的變更。

您已藉由設定應用程式,改為使用受控識別連線到 Blob,來移除 AzureWebJobsStorage 的儲存體連接字串需求。

注意

__accountName 語法對 AzureWebJobsStorage 連線而言是唯一的,無法用於其他儲存體連線。 若要了解如何定義其他連線,請檢查應用程式所使用的每個觸發程序和繫結的參考。

下一步

本教學課程已說明如何建立函數應用程式,而不將秘密儲存在其設定中。

在下一個教學課程中,您將了解如何在觸發程序和繫結連線中使用身分識別。