---
# System prepended metadata

title: '[Azure] 手把手體會 Azure Managed Identity'
tags: [Azure]

---

---
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)