如何以 Guest 身份將 Azure 的 Service Principal (服務主體) 加入角色指派 | The Will Will Web

The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

如何以 Guest 身份將 Azure 的 Service Principal (服務主體) 加入角色指派

最近加入到一個客戶的 Azure 訂用帳戶設定 CI/CD,在做這件事情之前,當然是先建立好 Service Principal (服務主體),然後才進行角色指派,讓該服務主體擁有必要的權限才能進行部署。不過建立完成後才發現,我忘記將 Storage account (儲存體帳號) 的 Storage Blob Data Contributor 角色指派給我建立好的 Service Principal (服務主體),以致於我無法透過 AzCopy 複製檔案進 Blob 容器中。最悲劇的地方,就是我的 Guest 身份竟然無法讀取 Service Principal (服務主體) 的任何資訊,導致我無法順利指派角色,這篇文章我就來說說我的最終解法!

問題描述

以下是角色指派的過程,你會發現你的 Guest 身份完全無法讀取到 Service Principal (服務主體) 的任何資訊,所以你是無法使用 Azure Portal 進行授權的:

Add role assignment

關於 Guest 在 Azure AD 中的權限,可以參見 Restrict guest access permissions in Azure Active Directory 說明。

為了這個問題,我有嘗試使用 Azure CLI 來進行授權

  • PowerShell

    az role assignment create `
        --role "Storage Blob Data Contributor" `
        --assignee sp-cicd `
        --scope "/subscriptions/$subscriptionId/resourceGroups/em-s/providers/Microsoft.Storage/storageAccounts/$storageAccountName"
    
  • Bash

    az role assignment create \
        --role "Storage Blob Data Contributor" \
        --assignee sp-cicd \
        --scope "/subscriptions/$subscriptionId/resourceGroups/em-s/providers/Microsoft.Storage/storageAccounts/$storageAccountName"
    

結果得到以下結果:

Insufficient privileges to complete the operation.

這下尷尬了,兩個方式都無法進行角色指派,但跟客戶申請「特權帳號」又需要好幾天時間,實在有點頭疼!

解決方案 1

我後來嘗試了很多方法,我透過 az role assignment create -h 找到了另一種指派角色的方法,也就是直接指定 --assignee-principal-type--assignee-object-id 參數,想不到竟然成功了! 😃

  • PowerShell

    az role assignment create `
        --role "Storage Blob Data Contributor" `
        --assignee-principal-type ServicePrincipal `
        --assignee-object-id 'f52ee8ae-1a33-4a2c-9f36-cdab66bd2ce8' `
        --scope "/subscriptions/$subscriptionId/resourceGroups/em-s/providers/Microsoft.Storage/storageAccounts/$storageAccountName"
    
  • Bash

    az role assignment create \
        --role "Storage Blob Data Contributor" \
        --assignee-principal-type ServicePrincipal \
        --assignee-object-id 'f52ee8ae-1a33-4a2c-9f36-cdab66bd2ce8' \
        --scope "/subscriptions/$subscriptionId/resourceGroups/em-s/providers/Microsoft.Storage/storageAccounts/$storageAccountName"
    

當你在使用 Azure CLI 建立 Service Principal (服務主體) 的時候,預設回傳的 JSON 屬性如下:

az ad sp create-for-rbac --name sp-cicd --role Contributor -o json
{
  "appId": "46e15d71-3451-0000-aa25-0ce6d2c913eb",
  "displayName": "sp-cicd",
  "name": "46e15d71-3451-0000-aa25-0ce6d2c913eb",
  "password": "9z$bTSfwDkCQtUrz2Gn6X3K4k@MD52ajjm",
  "tenant": "00000000-b057-4d4d-b7a8-ec2b4e8b9fd0"
}

而透過 az role assignment create 指派角色時,重點在於 --assignee-object-id 需要傳入 Service Principal (服務主體) 的 Object ID,但這應該如何取得呢?以下有兩種方法:

  1. 找任何一個 Azure AD 的 Member 幫你進 Azure AD 查詢 Service Principal (服務主體) 的 Object ID (如下圖示)

    App registrations > Object ID

  2. 切換到 Subscription (訂用帳戶) 的 Access Control (IAM) 查看 Service Principal (服務主體) 的詳細資料,然後從網址列查到 Object ID (如下圖示)

    Access Control (IAM)

    從網址列查到 Object ID

    因為你執行 az ad sp create-for-rbac 的時候,預設就會幫你建立一個 Access Control (IAM) 角色指派到 Subscription (訂用帳戶),因此你可以用這招查到 Service Principal (服務主體) 的 Object ID

使用 PowerShell 查詢服務主體 Object ID 的方法

還有一種取得 Object ID 的方法是透過 Windows PowerShell 的 AzureAD 模組 下的 Get-AzureADServicePrincipal Cmdlet,這個 Cmdlet 可以直接透過 Service Principal (服務主體) 的 顯示名稱 (displayName) 來獲取 Azure AD 中的完整資訊,其中當然包含了 Object ID 屬性!

  1. 請開啟 Windows PowerShell 視窗

  2. 安裝 AzureAD 模組

    Install-Module AzureAD
    
  3. 匯入 AzureAD 模組

    Import-Module AzureAD
    

    如果你使用 PowerShell Core 的話,請務必改用以下命令匯入,否則你將無法連接 AzureAD:

    Import-Module AzureAD -UseWindowsPowershell
    
  4. 指定 TenantId 連接 AzureAD 目錄

    $tenantId = '00000000-b057-4d4d-b7a8-ec2b4e8b9fd0'
    Connect-AzureAD -TenantId $tenantId
    
  5. 指定 TenantId 連接 AzureAD 目錄

    Get-AzureADServicePrincipal -Filter "DisplayName eq 'sp-cicd'"
    Get-AzureADServicePrincipal -Filter "DisplayName eq 'sp-cicd'" | fl
    

    預期結果:

    ObjectId                             AppId                                DisplayName
    --------                             -----                                -----------
    f52ee8ae-1a33-4a2c-9f36-cdab66bd2ce8 cf3ac9e0-16b1-4d4f-8f8a-da393cf84c6d sp-cicd
    

相關連結