--- title: '[Azure] 手把手體會 Azure Managed Identity' --- <!-- ## 前言 --> ## 簡介 Managed Identity 是 Azure 提供的一種身份服務,專為 Azure 資源(如虛擬機、App Service、Functions 等)設計,用於簡化對其他 Azure 資源的安全存取。 啟用 Managed Identity 後,不需要手動管理資源的密碼或憑證,Azure 會自動為資源管理存取的權限。 Managed Identity 分為兩種類型 * System-assigned Managed Identity:與資源一對一綁定,資源刪除時,身份也會刪除 * User-assigned Managed Identity:獨立於資源,可以在多個資源之間重複使用 ## 開始使用 實作將透過 Azure App Service 進行,啟用 Managed Identity 後驗證是否正確以指定權限存取 Azure 資源。 ### 指令:建立 App Service ```bash! # 透過 az-cli 登入 Azure az login # 建立資源群組 az group create -n <name> --location japanwest # 建立 App Service Plan (價格方案) az appservice plan create -n<name> -g <group-name> --sku FREE --is-linux # 建立 App Service az webapp create -n jj-appsvc -g jj-identity-gp -p <plan-name> --runtime "NODE:20-lts" ``` 執行完以上指令建立完相關的資源後,可以回到 [Azure Portal](https://portal.azure.com/#home) 查看。 ### 啟用身分識別及設定角色指派 * 使用 Azure CLI 指令 ```bash! az webapp identity assign -g <group-name> -n <webapp-name> --role reader --scope $(az group show -n <group-name> --query id --output tsv) ``` #### * 使用 Azure Portal 進入 Azure Portal 後,在建立出來的 App Service 開啟「系統指派」身分識別。 ![image](https://hackmd.io/_uploads/Hk2Akn3L1x.png) * 選擇角色指派 身分識別啟用後,在角色指派中設定對於 Azure 資源的存取權限,舉例:指定 App Service 可以對資源群組以 Reader 的角色進行操作。 ![image](https://hackmd.io/_uploads/H1jIWhh81e.png) ### 以 REST API 方式驗證 啟用身分識別以及設定角色指派完成後,以下步驟以 API 方式存取 Azure 資源 * SSH 進入 App Service 後,執行以下指令取得 JWT Token ```bash! curl "$IDENTITY_ENDPOINT?api-version=2019-08-01&resource=https://management.azure.com/" \ -H "Metadata: true" \ -H "X-IDENTITY-HEADER: $IDENTITY_HEADER" ``` * 特別說明 :::info 在 App Service 開啟身分識別後會自動新增兩個系統變數,分別為 `IDENTITY_ENDPOINT` 和 `IDENTITY_HEADER`,`IDENTITY_ENDPOINT` 為用來頒發 Token 的 Endpoint,`IDENTITY_HEADER` 為安全標頭,需帶在 `X-IDENTITY-HEADER`,以防止 SSRF 攻擊。 ::: * 取得 JWT Token 回傳結果 ```json { "access_token": "<jwt-token>", "expires_on": "1736323721", "resource": "https://management.azure.com/", "token_type": "Bearer", "client_id": "<client-id>" } ``` * 呼叫 ARM API 取得資源群組中所有的資源 ```bash! access_token="<access_token>" subscription_id="<subscription_id>" curl "https://management.azure.com/subscriptions/$subscription_id/resourceGroups/<group-name>/resources?api-version=2021-04-01" -H "Authorization: Bearer $access_token" ``` * 取得訂閱中的資源群組 ```json { "value": [ { "id": "<resource-id>", "name": "jj-vm-ip", "type": "Microsoft.Network/publicIPAddresses", "sku": { "name": "Basic" }, "location": "japaneast" } ... 以下省略 ] } ``` * 沒有存取權限時會顯示以下結果 ```json! { "error": { "code": "AuthorizationFailed", "message": "The client '<client-id>' with object id '<object-id>' does not have authorization to perform action 'Microsoft.Resources/subscriptions/resourceGroups/read' over scope '<subscription>' or the scope is invalid. If access was recently granted, please refresh your credentials." } } ``` ## 延伸閱讀 * [如何使用 App Service 和 Azure Functions 的受控身分識別](https://learn.microsoft.com/zh-tw/azure/app-service/overview-managed-identity?tabs=portal%2Chttp) * [什麼是 Azure 角色型存取控制 (Azure RBAC)](https://learn.microsoft.com/zh-tw/azure/role-based-access-control/overview) * [Azure REST API 參考](https://learn.microsoft.com/zh-tw/rest/api/gettingstarted/) * [在 Linux 上安裝 Azure CLI](https://learn.microsoft.com/zh-tw/cli/azure/install-azure-cli-linux?pivots=apt) * [az webapp identity](https://learn.microsoft.com/en-us/cli/azure/webapp/identity?view=azure-cli-latest)