問題描述
PowerShell 指令碼呼叫Azure REST API, 但是所有的API都需要進行許可權驗證。要在請求的Header部分帶上Authorization引數,並用來對List Resource Group介面進行授權,然後顯示Resource Group的Name,Location,和ID ...
問題解答
第一步:在Azure AD中註冊應用,該應用表示執行PowerShell Script的客戶端擁有訪問Subscription下資源的許可權。如無,則會出現 AuthorizationFailed 錯誤,詳見附錄一:許可權問題
-
在瀏覽器上的新標籤頁中開啟 Azure 門戶。
-
導航到“應用註冊”以在 Active Directory 中註冊應用。
-
選擇“新註冊”。 在“註冊應用程式”頁上,將值設定如下:
- 將“名稱”設定為一個有意義的名稱。 例如,powershell-client
- 將“支援的帳戶型別”設定為“僅限此組織目錄中的帳戶”。
- 選擇“註冊” 。
-
註冊應用程式之後,從“概述”頁複製“應用程式(客戶端) ID” 和 “ 目錄 ”。
-
在邊側選單的“管理”部分下,選擇“證書和機密” 。
-
在“證書和機密”頁中,選擇“客戶端機密”下的“新建客戶端機密”按鈕 。
- 輸入“說明”。
- 為“過期”選擇任一選項。
- 選擇“新增” 。
-
在離開頁面之前複製客戶端的“機密 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
執行結果:
附錄一:許可權問題
錯誤訊息:
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
錯誤截圖:
解決辦法:
在門戶中進入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 - List:https://docs.microsoft.com/en-us/rest/api/resources/resource-groups/list
Postman獲取Azure AD中註冊應用程式的授權Token,及為Azure REST API設定Authorization:https://www.cnblogs.com/lulight/p/14279338.html