【Azure 環境】用 PowerShell 呼叫 AAD Token, 以及呼叫Azure REST API(如資源組列表)

路邊兩盞燈發表於2021-11-14

問題描述

PowerShell 指令碼呼叫Azure REST API, 但是所有的API都需要進行許可權驗證。要在請求的Header部分帶上Authorization引數,並用來對List Resource Group介面進行授權,然後顯示Resource Group的Name,Location,和ID ...

【Azure 環境】用 PowerShell 呼叫 AAD Token, 以及呼叫Azure REST API(如資源組列表)

問題解答

第一步:在Azure AD中註冊應用,該應用表示執行PowerShell Script的客戶端擁有訪問Subscription下資源的許可權。如無,則會出現 AuthorizationFailed 錯誤,詳見附錄一:許可權問題

  1. 在瀏覽器上的新標籤頁中開啟 Azure 門戶。

  2. 導航到“應用註冊”以在 Active Directory 中註冊應用。

  3. 選擇“新註冊”。 在“註冊應用程式”頁上,將值設定如下:

    • 將“名稱”設定為一個有意義的名稱。 例如,powershell-client
    • 將“支援的帳戶型別”設定為“僅限此組織目錄中的帳戶”。
    • 選擇“註冊” 。
  4. 註冊應用程式之後,從“概述”頁複製“應用程式(客戶端) ID” 和 “ 目錄 ”。

  5. 在邊側選單的“管理”部分下,選擇“證書和機密” 。

  6. 在“證書和機密”頁中,選擇“客戶端機密”下的“新建客戶端機密”按鈕 。

    • 輸入“說明”。
    • 為“過期”選擇任一選項。
    • 選擇“新增” 。
  7. 在離開頁面之前複製客戶端的“機密 ID”。 稍後指令碼中需要用到此值。

 

第二步:在下面指令碼中替換自己的 tenantId, applicationId secret

#===============================================
# 2021-11-14 通過Azure AD中的註冊應用獲取Access Token
# 
# Azure AD App Registrations: https://portal.azure.cn/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps
# 【Azure Developer】使用Postman獲取Azure AD中註冊應用程式的授權Token,及為Azure REST API設定Authorization: https://www.cnblogs.com/lulight/p/14279338.html
#===============================================


$tenantId='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
$applicationId='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
$secret='-xxxx~xxxxxxxxxxxxxxxxxxxxxxxx'

$param = @{
    Uri ="https://login.chinacloudapi.cn/$tenantId/oauth2/token";
    Method = 'Post';
    Body = @{
        grant_type = 'client_credentials';
        resource = 'https://management.chinacloudapi.cn';
        client_id = $applicationId;
        client_secret = $secret
    }
}

Write-Host '呼叫Token介面 .. ' -ForegroundColor DarkYellow
$result = Invoke-RestMethod @param
$result


#===============================================
#
# 使用Token作為Authorization,呼叫Resource Groups - List: https://docs.microsoft.com/en-us/rest/api/resources/resource-groups/list
#
#===============================================


$subscriptionId = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
$token = $result.access_token

$param_rgList = @{
    Uri = "https://management.chinacloudapi.cn/subscriptions/$subscriptionId/resourcegroups?api-version=2020-06-01";
    ContentType = 'application/json';
    Method = 'GET'
    Headers = @{
        Authorization = "Bearer $token";
        host = "management.chinacloudapi.cn"
    }
}

Write-Host '呼叫 Resource Groups - List 介面 .. ' -ForegroundColor DarkYellow
$rgList =  Invoke-RestMethod @param_rgList
$rgList.value | Select-Object name, location, id

執行結果:

【Azure 環境】用 PowerShell 呼叫 AAD Token, 以及呼叫Azure REST API(如資源組列表)

 

 

附錄一:許可權問題

錯誤訊息:

Invoke-RestMethod : {"error":{"code":"AuthorizationFailed","message":"The client '0b807bf1-40db-4e0c-888f-380b9b558cf1' with object id '0b807bf1-40db-4e0c-888f-380b9b558cf1' does not have authorization 
to perform action 'Microsoft.Resources/subscriptions/resourcegroups/read' over scope '/subscriptions/a9dc7515-7692-4316-9ad4-762f383eec10' or the scope is invalid. If access was recently granted, 
please refresh your credentials."}}
At line:49 char:12
+ $rgList =  Invoke-RestMethod @param_rgList
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

錯誤截圖:

【Azure 環境】用 PowerShell 呼叫 AAD Token, 以及呼叫Azure REST API(如資源組列表)

解決辦法:

在門戶中進入Subscriptions頁面,對註冊應用賦予Reader許可權即可。

1) 進入Azure Subscriptions頁面:https://portal.azure.cn/#blade/Microsoft_Azure_Billing/SubscriptionsBlade

2) 選中訂閱,在Access Control(IAM)中對第一步中 AAD的註冊應用賦予Reader許可權。   

 

 

附錄二:PowerShell中URL後攜帶引數的‘?’需要轉義

因為PowerShell的變數名中後不能為符號,如 ? 等,需要新增 ` 作為轉義字元(高亮部分),改為 '?。

如:

$apiurl ="https://management.chinacloudapi.cn/.../$CloudServiceName?api-version=2015-06-01"

應修改為:

$apiurl ="https://management.chinacloudapi.cn/.../$CloudServiceName`?api-version=2015-06-01"

 

 

 

參考資料

Resource Groups - Listhttps://docs.microsoft.com/en-us/rest/api/resources/resource-groups/list

Postman獲取Azure AD中註冊應用程式的授權Token,及為Azure REST API設定Authorizationhttps://www.cnblogs.com/lulight/p/14279338.html

 

相關文章