教學課程:建立函數應用程式,其會使用身分識別而不是秘密連線到 Azure 服務
本教學課程說明如何儘可能使用 Microsoft Entra 身分識別而不是秘密或連接字串,來設定函數應用程式。 使用身分識別可協助您避免意外洩漏敏感性秘密,並更清楚地了解資料存取方式。 若要深入了解身分識別型連線,請參閱設定身分識別型連線。
雖然顯示的程序通常適用於所有語言,但本教學課程目前專門用來支援 Windows 上的 C# 類別庫函數。
在本教學課程中,您會了解如何:
- 使用 ARM 範本在 Azure 中建立函數應用程式
- 在函數應用程式上同時啟用系統指派和使用者指派的受控識別
- 建立授與其他資源權限的角色指派
- 將無法取代為身分識別的秘密移至 Azure Key Vault
- 設定應用程式以使用其受控識別連線到預設主機儲存體
在完成本教學課程之後,您應該完成後續教學課程,其會說明如何將身分識別型連線 (而非密碼) 與觸發程序和繫結搭配使用。
必要條件
具有有效訂用帳戶的 Azure 帳戶。 免費建立帳戶。
Azure Functions Core Tools 4.x 版。
為何使用身分識別?
管理秘密和認證是各種規模的小組面臨的共同挑戰。 秘密必須受到保護,以防範遭人竊取或意外洩漏,且您可能需要定期輪換這些秘密。 許多 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),以決定誰可以從保存庫讀取秘密。
在 Azure 入口網站中,選擇 [建立資源 (+)]。
在 [建立資源] 頁面上,選取 [安全性]>[金鑰保存庫]。
在 [基本] 頁面上,使用下表來設定金鑰保存庫。
選項 建議的值 描述 訂用帳戶 您的訂用帳戶 在其下建立這個新函數應用程式的訂用帳戶。 資源群組 myResourceGroup 在其中建立函數應用程式的新資源群組名稱。 金鑰保存庫名稱 全域唯一的名稱 識別新金鑰保存庫的名稱。 保存庫名稱只能包含英數字元和虛線,且不得以數字開頭。 定價層 標準 計費選項。 對於本教學課程,標準就足夠了。 區域 慣用區域 選擇的區域應靠近您或靠近函式將會存取的其他服務。 針對 [復原選項] 區段使用預設選取項目。
記下您所使用的名稱,以供稍後使用。
選取 [下一步: 存取原則] 以瀏覽至 [存取原則] 索引標籤。
在 [權限模型] 下,選擇 [Azure 角色型存取控制]
選取 [檢閱 + 建立]。 檢閱設定,然後選取 [建立]。
設定應用程式的身分識別和權限
若要使用 Azure Key Vault,您的應用程式必須具有可獲授與讀取秘密權限的身分識別。 此應用程式會使用一個使用者指派的身分識別,以便甚至在建立應用程式之前即設定權限。 如需深入了解適用於 Azure Functions 的受控識別,請參閱如何在 Azure Functions 中使用受控識別。
在 Azure 入口網站中,選擇 [建立資源 (+)]。
在 [建立資源] 頁面上,選取 [身分識別]>[使用者指派的受控識別]。
在 [基本] 頁面上,使用下表來設定身分識別。
選項 建議的值 描述 訂用帳戶 您的訂用帳戶 在其下建立這個新函數應用程式的訂用帳戶。 資源群組 myResourceGroup 在其中建立函數應用程式的新資源群組名稱。 區域 慣用區域 選擇的區域應靠近您或靠近函式將會存取的其他服務。 名稱 全域唯一的名稱 識別新使用者指派身分識別的名稱。 選取 [檢閱 + 建立]。 檢閱設定,然後選取 [建立]。
建立身分識別後,請在入口網站中瀏覽至該身分識別。 選取 [屬性],並記下 [資源識別碼] 以供稍後使用。
選取 [Azure 角色指派],然後選取 [新增角色指派 (預覽)]。
在 [新增角色指派 (預覽)] 頁面中,使用下表中所示的選項。
選項 建議的值 描述 範圍 Key Vault 範圍是角色指派套用至其中的一組資源。 範圍在較低層級繼承的層級。 例如,如果您選取訂用帳戶範圍,則角色指派會套用至訂用帳戶中的所有資源群組和資源。 訂用帳戶 您的訂用帳戶 在其下建立這個新函數應用程式的訂用帳戶。 資源 您的金鑰保存庫 您稍早建立的金鑰保存庫。 Role Key Vault 祕密使用者 角色是被授與的權限集合。 金鑰保存庫秘密使用者授權身分識別可從保存庫讀取秘密值。 選取 [儲存]。 當您重新整理身分識別的角色指派清單時,可能需要一或兩分鐘的時間才會顯示角色。
身分識別現在能夠讀取金鑰保存庫中所儲存的秘密。 稍後在本教學課程中,您會針對不同的用途新增其他角色指派。
產生用於建立函數應用程式的範本
因為建立函數應用程式的入口網站體驗不會與 Azure Key Vault 互動,所以您必須產生和編輯 Azure Resource Manager 範本。 然後,您可以使用此範本建立函數應用程式,從金鑰保存庫參考 Azure 檔案儲存體連接字串。
重要
在您編輯 ARM 範本之前,請不要建立函數應用程式。 必須在建立應用程式時設定 Azure 檔案儲存體設定。
在 Azure 入口網站中,選擇 [建立資源 (+)]。
在 [建立資源] 頁面上,選取[計算]>[函數應用程式]。
在 [基本] 頁面上,使用下表來設定函數應用程式。
選項 建議的值 描述 訂用帳戶 您的訂用帳戶 在其下建立這個新函數應用程式的訂用帳戶。 資源群組 myResourceGroup 在其中建立函數應用程式的新資源群組名稱。 函數應用程式名稱 全域唯一的名稱 用以識別新函式應用程式的名稱。 有效的字元是 a-z
(不區分大小寫)、0-9
和-
。發行 代碼 選擇要發佈程式碼檔案或 Docker 容器。 執行階段堆疊 .NET 本教學課程使用 .NET。 區域 慣用區域 選擇的區域應靠近您或靠近函式將會存取的其他服務。 選取 [檢閱 + 建立]。 您的應用程式會在 [裝載] 和 [監視] 頁面上使用預設值。 檢閱預設選項,這些選項包含在您產生的 ARM 範本中。
選擇 [下載範本進行自動化] (位於 [下一步] 按鈕右側),而不是在這裡建立函數應用程式。
在範本頁面中,選取 [部署],然後在 [自訂部署] 頁面中,選取 [編輯範本]。
編輯範本
您現在要編輯範本,以將 Azure 檔案儲存體連接字串儲存在金鑰保存庫中,並允許函數應用程式參考該字串。 確定您有先前各節中的下列值,然後再繼續進行:
- 使用者指派的身分識別資源識別碼
- 金鑰保存庫的名稱
注意
如果您將建立完整範本進行自動化,您想要包括身分識別和角色指派資源的定義,以及適當的 dependsOn
子句。 這會取代已使用入口網站的稍早步驟。 請參閱 Azure Resource Manager 指引和每個服務的文件。
在編輯器中,尋找
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'))]" ] },
在函數應用程式資源的定義 (已將
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'))]" ], // ... }
將下列範例中的
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
區塊也會設定系統指派的身分識別,您會在本教學課程稍後使用此身分識別。將
keyVaultReferenceIdentity
屬性新增至函數應用程式的properties
物件,如下列範例所示。 將 "IDENTITY_RESOURCE_ID" 替換成使用者指派的身分識別資源識別碼。{ // ... "properties": { "name": "[parameters('name')]", "keyVaultReferenceIdentity": "IDENTITY_RESOURCE_ID", // ... } }
您需要此設定,因為應用程式可能已設定多個使用者指派的身分識別。 每當您想要使用使用者指派的身分識別時,都必須使用識別碼加以指定。 系統指派的身分識別不需要以此方式指定,因為應用程式只能有一個身分識別。 許多使用受控識別的功能都假設其應該預設使用系統指派的受控識別。
尋找定義
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')]" },
將
value
欄位取代為秘密的參考,如下列範例所示。 將 "VAULT_NAME" 替換成您的金鑰保存庫名稱。{ "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING", "value": "[concat('@Microsoft.KeyVault(SecretUri=', reference(resourceId('Microsoft.KeyVault/vaults/secrets', 'VAULT_NAME', 'azurefilesconnectionstring')).secretUri, ')')]" },
選取 [儲存] 以儲存更新的 ARM 範本。
部署已修改的範本
確定您建立的選項 (包括 [資源群組]) 仍然正確,然後選取 [檢閱 + 建立]。
在您的範本驗證之後,請記下儲存體帳戶名稱,因為您稍後會使用此帳戶。 最後,選取 [建立] 以建立您的 Azure 資源,並將您的程式碼部署至函數應用程式。
在部署完成之後,選取 [移至資源群組],然後選取新的函數應用程式。
恭喜! 您已成功建立函數應用程式,從 Azure Key Vault 參考 Azure 檔案儲存體連接字串。
每當您的應用程式需要新增對秘密的參考時,您只需要定義新的應用程式設定,指向金鑰保存庫中儲存的值。 如需詳細資訊,請參閱 Azure Functions 的 Key Vault 參考。
提示
Application Insights 連接字串及其包括的檢測金鑰未被視為秘密,因此可以使用讀者權限從 App Insights 擷取。 您不需要將其移至金鑰保存庫,不過當然可以。
使用 AzureWebJobsStorage 的受控識別
接下來,您要使用您在先前步驟中為 AzureWebJobsStorage
連線設定的系統指派身分識別。 AzureWebJobsStorage
由 Azure Functions 執行階段以及數個觸發程序和繫結用來在多個執行中的執行個體之間進行協調。 您的函數應用程式必須運作,就像 Azure 檔案儲存體一樣,當您建立新的函數應用程式時,預設會使用連接字串進行設定。
將系統指派的身分識別存取權授與儲存體帳戶
與您先前搭配使用者指派的身分識別和金鑰保存庫所遵循的步驟類似,您現在要建立一個角色指派,將系統指派的身分識別存取權授與儲存體帳戶。
在 Azure 入口網站中,瀏覽至稍早使用函數應用程式建立的儲存體帳戶。
選取存取控制 (IAM)。 您可以在此頁面檢視及設定有權存取資源的人員。
選取 [新增],然後選取 [新增角色指派]。
搜尋儲存體 Blob 資料擁有者、選取該擁有者,然後選取 [下一步]
在 [成員] 索引標籤上的 [指派存取權的對象] 底下,選擇 [受控識別]
選取 [選取成員] 以開啟 [選取受控識別] 面板。
確認 [訂用帳戶] 是您稍早建立資源的訂用帳戶。
在 [受控識別] 選取器中,從 [系統指派的受控識別] 類別中選擇 [函數應用程式]。 「函數應用程式」標籤旁邊可能有一個以括號括住的數字,指出訂用帳戶中具有系統指派身分識別的應用程式數目。
您的應用程式應該會出現在輸入欄位下方的清單中。 如果畫面上未顯示,可以使用 [選取] 方塊篩選具有您應用程式名稱的結果。
選取您的應用程式。 該應用程式應該會向下移至 [選取的成員] 區段。 選擇選取。
在 [新增角色指派] 畫面上,選取 [檢閱 + 指派]。 檢閱設定,然後選取 [檢閱 + 指派]。
提示
如果想要針對 Blob 觸發的函數使用函數應用程式,您必須透過 AzureWebJobsStorage 所使用的帳戶,針對 儲存體帳戶參與者和儲存體佇列資料參與者角色重複這些步驟。 若要深入1 解,請參閱 Blob 觸發程序身分識別型連線。
編輯 AzureWebJobsStorage 設定
接下來,您要更新函數應用程式,以在其針對主機儲存體使用 Blob 服務時,使用其系統指派的身分識別。
重要
AzureWebJobsStorage
設定是由某些觸發程序和繫結使用,而且這些延伸模組也必須能夠使用身分識別型連線。 使用 Blob 觸發程序或事件中樞觸發程序的應用程式可能需要更新這些延伸模組。 因為沒有針對此應用程式定義的任何函式,所以還沒有任何問題。 若要深入了解此需求,請參閱使用身分識別連線到主機儲存體。
同樣地,在 Linux 使用量中使用伺服器端組建時,AzureWebJobsStorage
會用於部署成品。 在 Linux 使用量中啟用 AzureWebJobsStorage
的身分識別型連線時,您必須透過外部部署套件進行部署。
在 Azure 入口網站中,瀏覽至您的函式應用程式。
在您的函數應用程式中,展開 [設定],然後選取 [環境變數]。
在 [應用程式設定] 索引標籤中,選取 [AzureWebJobsStorage] 應用程式設定,然後根據下表加以編輯:
選項 建議的值 名描述 名稱 AzureWebJobsStorage__accountName 將名稱從 AzureWebJobsStorage 變更為確切的名稱 AzureWebJobsStorage__accountName
。 此設定會指示主機使用身分識別,而不是搜尋儲存的秘密。 新設定會使用雙底線 (__
) ,這是應用程式設定中的特殊字元。值 您的帳戶名稱 將連接字串中的名稱只更新為您的 StorageAccountName。 此組態會告知系統使用身分識別來連線到資源。
選取 [套用],然後選取 [套用] 和 [確認],以儲存變更並重新啟動應用程式函式。
現在您已設定應用程式,改為使用受控識別連線到 Blob,來移除 AzureWebJobsStorage 的儲存體連接字串需求。
注意
__accountName
語法對 AzureWebJobsStorage 連線而言是唯一的,無法用於其他儲存體連線。 若要了解如何定義其他連線,請檢查應用程式所使用的每個觸發程序和繫結的參考。
下一步
本教學課程已說明如何建立函數應用程式,而不將秘密儲存在其設定中。
請續進行下一個教學課程,了解如何在觸發程序和繫結連線中使用身分識別。