如何使用 App Service 和 Azure Functions 的受控身分識別
本文內容
注意
從 2024 年 6 月 1 日起,所有新建立的 App Service 應用程式都可以選擇使用命名慣例 <app-name>-<random-hash>.<region>.azurewebsites.net
來產生唯一的預設主機名稱。 現有的應用程式名稱將保持不變。
範例: myapp-ds27dh7271aah175.westus-01.azurewebsites.net
如需詳細資料,請參閱 App Service 資源的唯一預設主機名稱 (英文)。
本文示範如何為 App Service 和 Azure Functions 應用程式建立受控身分識別,並用於存取其他資源。
Microsoft Entra ID 的受控識別,可讓應用程式輕鬆存取其他受到 Microsoft Entra 保護的資源 (例如 Azure Key Vault)。 身分識別由 Azure 平台負責管理,因此您不需要佈建或輪替任何密碼。 如需有關 Microsoft Entra ID 中受控識別的詳細資訊,請參閱適用於 Azure 資源的受控識別 。
您的應用程式可以授與兩種類型的身分識別:
系統指派的身分識別 會繫結至應用程式,並在刪除該應用程式時一併刪除。 應用程式只能有一個系統指派的身分識別。
使用者指派的身分識別 是一項獨立 Azure 資源,可指派給您的應用程式。 應用程式可以有多個使用者指派的身分識別,而一個使用者指派的身分識別可以指派給多個 Azure 資源,例如兩個 App Service 應用程式。
受控識別設定是位置的特有項目。 若要在入口網站設定部署位置的受控識別,請先導覽至位置。 若要使用 Azure 入口網站,在 Microsoft Entra 租用戶中尋找 Web 應用程式或部署位置的受控識別,請直接從租用戶的 [概觀] 頁面搜尋。 位置名稱通常類似 <app-name>/slots/<slot-name>
。
此影片顯示如何使用 App Service 的受控識別。
下列各節也會說明影片中的步驟。
新增系統指派的身分識別
在 Azure 入口網站 中,於左側瀏覽窗格中的 [設定] 群組底下存取應用程式的設定。
選取 [身分識別]。
在 [系統指派] 索引標籤內,將 [狀態] 切換為 [開啟] 。 按一下 [檔案] 。
執行 az webapp identity assign
命令以建立系統指派的身分識別:
az webapp identity assign --name myApp --resource-group myResourceGroup
針對 App Service
執行 Set-AzWebApp -AssignIdentity
命令,為 App Service 建立系統指派的身分識別:
Set-AzWebApp -AssignIdentity $true -Name <app-name> -ResourceGroupName <group-name>
針對 Functions
執行 Update-AzFunctionApp -IdentityType
命令,為函數應用程式建立系統指派的身分識別:
Update-AzFunctionApp -Name $functionAppName -ResourceGroupName $resourceGroupName -IdentityType SystemAssigned
您可以使用 Azure Resource Manager 範本來將 Azure 資源的部署自動化。 若要深入了解如何部署到 App Service 和 Functions,請參閱在 App Service 中將資源部署自動化 和在 Azure Functions 中將資源部署自動化 。
對於所有 Microsoft.Web/sites
型別的資源來說,您可以在資源定義中加入以下屬性,以建立採用身分識別的資源:
"identity": {
"type": "SystemAssigned"
}
新增系統指派的類型能告訴 Azure 該如何建立及管理應用程式的身分識別。
例如,Web 應用程式範本應如下列 JSON 所示:
{
"apiVersion": "2022-03-01",
"type": "Microsoft.Web/sites",
"name": "[variables('appName')]",
"location": "[resourceGroup().location]",
"identity": {
"type": "SystemAssigned"
},
"properties": {
"name": "[variables('appName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"hostingEnvironment": "",
"clientAffinityEnabled": false,
"alwaysOn": true
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]"
]
}
當網站建立時,它擁有以下額外屬性:
"identity": {
"type": "SystemAssigned",
"tenantId": "<tenant-id>",
"principalId": "<principal-id>"
}
tenantId 屬性能辨識身分識別所隸屬的 Microsoft Entra 租用戶。 principalId 是應用程式新身分識別的唯一識別碼。 在 Microsoft Entra ID 內,服務主體的名稱與您提供給 App Service 或 Azure Functions 執行個體的名稱相同。
若稍後階段必須參考範本中的這些屬性,則可透過reference()
範本函數 使用 'Full'
旗標來進行,如下列範例所示:
{
"tenantId": "[reference(resourceId('Microsoft.Web/sites', variables('appName')), '2018-02-01', 'Full').identity.tenantId]",
"objectId": "[reference(resourceId('Microsoft.Web/sites', variables('appName')), '2018-02-01', 'Full').identity.principalId]",
}
新增使用者指派的身分識別
利用使用者指派的身分識別建立應用程式會需要您建立身分識別,然後將其資源識別碼新增到您的應用程式設定中。
首先,您必須建立使用者指派的身分識別資源。
根據這些指示 建立使用者指派的受控識別資源。
在應用程式頁面的左側瀏覽中,向下捲動至 [設定] 群組。
選取 [身分識別]。
選取 [使用者指派] >[新增] 。
搜尋並選取您之前建立的身分識別,然後選取 [新增] 。
選取 [新增] 後,應用程式就會重新啟動。
建立使用者指派的身分識別。
az identity create --resource-group <group-name> --name <identity-name>
執行 az webapp identity assign
命令以將身分識別指派給應用程式。
az webapp identity assign --resource-group <group-name> --name <app-name> --identities <identity-id>
針對 App Service
目前不支援在 App Service 中新增使用者指派的身分識別。
針對 Functions
建立使用者指派的身分識別。
Install-Module -Name Az.ManagedServiceIdentity -AllowPrerelease
$userAssignedIdentity = New-AzUserAssignedIdentity -Name $userAssignedIdentityName -ResourceGroupName <group-name>
執行 Update-AzFunctionApp -IdentityType UserAssigned -IdentityId
命令,以指派 Functions 中的身分識別:
Update-AzFunctionApp -Name <app-name> -ResourceGroupName <group-name> -IdentityType UserAssigned -IdentityId $userAssignedIdentity.Id
您可以使用 Azure Resource Manager 範本來將 Azure 資源的部署自動化。 若要深入了解如何部署到 App Service 和 Functions,請參閱在 App Service 中將資源部署自動化 和在 Azure Functions 中將資源部署自動化 。
對於所有 Microsoft.Web/sites
型別的資源來說,您可以在資源定義中加入以下區塊,以所需之身分識別的資源識別碼取代 <resource-id>
,來建立採用身分識別的資源:
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"<resource-id>": {}
}
}
注意
應用程式可以同時具有系統指派的身分識別和使用者指派的身分識別。 在此情況下,type
屬性將會是 SystemAssigned,UserAssigned
新增使用者指派的類型,會告訴 Azure 使用針對您應用程式指定的使用者指派身分識別。
例如,Web 應用程式範本應如下列 JSON 所示:
{
"apiVersion": "2022-03-01",
"type": "Microsoft.Web/sites",
"name": "[variables('appName')]",
"location": "[resourceGroup().location]",
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('identityName'))]": {}
}
},
"properties": {
"name": "[variables('appName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"hostingEnvironment": "",
"clientAffinityEnabled": false,
"alwaysOn": true
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('identityName'))]"
]
}
當網站建立時,它擁有以下額外屬性:
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"<resource-id>": {
"principalId": "<principal-id>",
"clientId": "<client-id>"
}
}
}
對於 Microsoft Entra 管理所用的身分識別,principalId 是唯一的識別碼。 clientId 是應用程式新身分識別的唯一識別碼,用來指定要在執行階段呼叫期間使用的身分識別。
您可能必須設定目標資源,讓應用程式或函數得以存取。 例如,若您要求權杖 以存取 Key Vault,則須新增存取原則並包含該應用程式或函數的受控識別。 否則即使呼叫 Key Vault 時使用有效權杖,仍將遭拒絕。 對 Azure SQL Database 而言,也是如此。 若要深入瞭解哪些資源支援 Microsoft Entra 權杖,請參閱支援 Microsoft Entra 驗證的 Azure 服務 。
重要
受控身分識別的後端服務會將每個資源的 URI 快取保留大約 24 小時。 所以,對於受控識別的群組或角色成員資格,變更可能需要數小時才會生效。 目前無法在到期前強制重新整理受控識別的權杖。 如果您變更受控識別的群組或角色成員資格以新增或移除權限,您可能需要等候數小時,讓使用身分識別的 Azure 資源具有正確的存取權。 如需群組或角色成員資格的替代方案,請參閱 使用受控識別進行授權 的限制。
以應用程式程式碼連線至 Azure 服務
應用程式可透過受控識別取得權杖,以存取受 Microsoft Entra ID 保護的 Azure 資源,例如 Azure SQL Database、Azure Key Vault 和 Azure 儲存體。 這些權杖代表存取資源的應用程式,而不是任何特定的應用程式使用者。
App Service 和 Azure Functions 提供內部可存取的 REST 端點 來擷取權杖。 您可使用標準 HTTP GET 存取應用程式內的 REST 端點,這可每種程式語言的通用 HTTP 用戶端進行實作。 針對 .NET、JavaScript、JAVA 和 Python,Azure 身分識別用戶端程式庫會在此 REST 端點上提供抽象概念,並簡化開發體驗。 連線至其他 Azure 服務就如同將認證物件新增至服務特定用戶端一樣簡單。
原始 HTTP GET 要求會使用 兩個提供的環境變數 ,如下所示:
GET /MSI/token?resource=https://vault.azure.net&api-version=2019-08-01 HTTP/1.1
Host: <ip-address-:-port-in-IDENTITY_ENDPOINT>
X-IDENTITY-HEADER: <value-of-IDENTITY_HEADER>
範例回應如下所示:
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "eyJ0eXAi…",
"expires_on": "1586984735",
"resource": "https://vault.azure.net",
"token_type": "Bearer",
"client_id": "00001111-aaaa-2222-bbbb-3333cccc4444"
}
該回應與 Microsoft Entra 服務對服務存取權杖要求的回應 相同。 若要存取 Key Vault,請將 access_token
的值新增至與保存庫連線的用戶端。
使用下列指令碼指定 Azure 服務的資源 URI,以便從本機端點擷取權杖:
$resourceURI = "https://<AAD-resource-URI-for-resource-to-obtain-token>"
$tokenAuthURI = $env:IDENTITY_ENDPOINT + "?resource=$resourceURI&api-version=2019-08-01"
$tokenResponse = Invoke-RestMethod -Method Get -Headers @{"X-IDENTITY-HEADER"="$env:IDENTITY_HEADER"} -Uri $tokenAuthURI
$accessToken = $tokenResponse.access_token
如需 REST 端點的詳細資訊,請參閱 REST 端點參考 。
移除身分識別
當您移除系統指派的身分識別時,隨即從 Microsoft Entra ID 中刪除。 刪除應用程式資源本身時,系統指派的身分識別也會從 Microsoft Entra ID 自動移除。
在應用程式頁面的左側瀏覽中,向下捲動至 [設定] 群組。
選取 [身分識別]。 接著依據身分識別類型,遵循步驟:
系統指派的身分識別 :在 [系統指派] 索引標籤內,將 [狀態] 切換為 [關閉] 。 按一下 [檔案] 。
使用者指派的身分識別 :選取 [使用者指派 ] 索引標籤,選取身分識別的核取方塊,然後選取 [移除 ]。 選取是 以確認。
若要移除系統指派的身分識別:
az webapp identity remove --name <app-name> --resource-group <group-name>
若要移除一或多個使用者指派的身分識別:
az webapp identity remove --name <app-name> --resource-group <group-name> --identities <identity-id1> <identity-id2> ...
您也可在 --identities
中指定 [system]
,以移除系統指派的身分識別。
針對 App Service
執行 Set-AzWebApp -AssignIdentity
命令,為 App Service 移除系統指派的身分識別:
Set-AzWebApp -AssignIdentity $false -Name <app-name> -ResourceGroupName <group-name>
針對 Functions
若要移除 Azure PowerShell 中的所有身分識別 (僅限 Azure Functions):
# Update an existing function app to have IdentityType "None".
Update-AzFunctionApp -Name $functionAppName -ResourceGroupName $resourceGroupName -IdentityType None
若要移除 ARM 範本中的所有身分識別:
"identity": {
"type": "None"
}
注意
還可以設定另一個應用程式設定:WEBSITE_DISABLE_MSI,這只會停用本機權杖服務。 不過,系統會將身分識別留在原地,且工具仍會將受控身分識別顯示為「開啟」或「已啟用」。因此,不建議使用這個設定。
REST 端點參考
具有受控識別的應用程式可定義兩個環境變數來提供此端點:
IDENTITY_ENDPOINT - 本機權杖服務的 URL。
IDENTITY_HEADER - 用於協助減輕伺服器端要求偽造 (SSRF) 攻擊的標頭。 值會由平台旋轉。
IDENTITY_ENDPOINT 是應用程式要求權杖的來源本機 URL。 若要取得資源的權杖,請向該端點提出包含以下參數的 HTTP GET 要求:
參數名稱
In
描述
resource
查詢
資源的 Microsoft Entra 資源 URI,也就是要取得權杖的目標資源。 這可能是其中一個支援 Microsoft Entra 驗證的 Azure 服務 ,或任何其他資源 URI。
api-version
查詢
要使用的權杖 API 版本。 使用 2019-08-01
。
X-IDENTITY-HEADER
頁首
IDENTITY_HEADER 環境變數的值。 此標頭用來協助減輕伺服器端要求偽造 (SSRF) 攻擊。
client_id
查詢
(選擇性) 要使用的使用者指派身分識別,其用戶端識別碼。 不能用於包含 principal_id
、mi_res_id
或 object_id
的要求。 如果省略所有識別碼參數 (client_id
、principal_id
、object_id
和 mi_res_id
),則會使用系統指派的身分識別。
principal_id
查詢
(選擇性) 要使用的使用者指派身分識別,其主體識別碼。 object_id
是可代替使用的別名。 不能用於包含 client_id、mi_res_id 或 object_id 的要求。 如果省略所有識別碼參數 (client_id
、principal_id
、object_id
和 mi_res_id
),則會使用系統指派的身分識別。
mi_res_id
查詢
(選擇性) 要使用的使用者指派身分識別,其 Azure 資源識別碼。 不能用於包含 principal_id
、client_id
或 object_id
的要求。 如果省略所有識別碼參數 (client_id
、principal_id
、object_id
和 mi_res_id
),則會使用系統指派的身分識別。
重要
如果您嘗試取得使用者指派身分識別的權杖,則必須包含其中一個選擇性屬性。 否則,權杖服務會嘗試取得系統指派身分識別的權杖,這不一定會存在。
下一步