Try   HackMD

簡介

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

# 透過 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 查看。

啟用身分識別及設定角色指派

  • 使用 Azure CLI 指令
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 Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →

  • 選擇角色指派
    身分識別啟用後,在角色指派中設定對於 Azure 資源的存取權限,舉例:指定 App Service 可以對資源群組以 Reader 的角色進行操作。

    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →

以 REST API 方式驗證

啟用身分識別以及設定角色指派完成後,以下步驟以 API 方式存取 Azure 資源

  • SSH 進入 App Service 後,執行以下指令取得 JWT Token
curl "$IDENTITY_ENDPOINT?api-version=2019-08-01&resource=https://management.azure.com/" \
-H "Metadata: true" \
-H "X-IDENTITY-HEADER: $IDENTITY_HEADER"
  • 特別說明

在 App Service 開啟身分識別後會自動新增兩個系統變數,分別為 IDENTITY_ENDPOINTIDENTITY_HEADERIDENTITY_ENDPOINT 為用來頒發 Token 的 Endpoint,IDENTITY_HEADER 為安全標頭,需帶在 X-IDENTITY-HEADER,以防止 SSRF 攻擊。

  • 取得 JWT Token 回傳結果
{
    "access_token": "<jwt-token>",
    "expires_on": "1736323721",
    "resource": "https://management.azure.com/",
    "token_type": "Bearer",
    "client_id": "<client-id>"
}
  • 呼叫 ARM API 取得資源群組中所有的資源
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"
  • 取得訂閱中的資源群組
{
    "value": [
        {
            "id": "<resource-id>",
            "name": "jj-vm-ip",
            "type": "Microsoft.Network/publicIPAddresses",
            "sku": {
                "name": "Basic"
            },
            "location": "japaneast"
        }
        ... 以下省略
    ]
}
  • 沒有存取權限時會顯示以下結果
{
    "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."
    }
}

延伸閱讀