【Azure Developer】使用 Azure Python SDK時,遇見 The resource principal named https://management.azure.com was not found in the tenant China Azure問題的解決辦法

問題描述

在使用Python SDK時候,登錄到China Azure (Mooncake)並訪問AlertsManagement資源時候,時常遇見  EnvironmentCredential: Authentication failed 的錯誤消息。

Python 程式碼:

from azure.identity import DefaultAzureCredential
from azure.mgmt.alertsmanagement import AlertsManagementClient

# Acquire a credential object using CLI-based authentication.
credential = DefaultAzureCredential()
subscription_id = "xxxx-xxxx-xxxx-xxxx-xxxx"

alertClient = AlertsManagementClient(credential,subscription_id,base_url="//management.chinacloudapi.cn/")

rules = alertClient.smart_detector_alert_rules.list()
for rule in rules:
    print("Rule Name: " + rule.name)

錯誤消息:

PS C:\LBWorkSpace\MyCode\46-alertrule-python> python getrule.py
DefaultAzureCredential failed to retrieve a token from the included credentials.
Attempted credentials:
        EnvironmentCredential: Authentication failed: AADSTS500011: The resource principal named //management.azure.com was not found in the tenant named xxx Mooncake. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.
Trace ID: xxxxxxxx-xxxx-xxxx-xxxx-9e130dbf7900
Correlation ID: xxxxxxxx-xxxx-xxxx-xxxx-46769c9e1e10
Timestamp: 2022-01-27 12:09:35Z
To mitigate this issue, please refer to the troubleshooting guidelines here at //aka.ms/azsdk/python/identity/defaultazurecredential/troubleshoot.
Traceback (most recent call last):
  File "C:\LBWorkSpace\MyCode\46-alertrule-python\getrule.py", line 15, in <module>
    for rule in rules:
  File "C:\Users\bulu\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\core\paging.py", line 129, in __next__
    return next(self._page_iterator)
  File "C:\Users\bulu\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\core\paging.py", line 76, in __next__
    self._response = self._get_next(self.continuation_token)
  File "C:\Users\bulu\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\core\pipeline\policies\_redirect.py", line 158, in send
    response = self.next.send(request)
  File "C:\Users\bulu\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\core\pipeline\policies\_retry.py", line 445, in send
    response = self.next.send(request)
  File "C:\Users\bulu\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\core\pipeline\policies\_authentication.py", line 117, in send
    self.on_request(request)
  File "C:\Users\bulu\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\core\pipeline\policies\_authentication.py", line 94, in on_request
    self._token = self._credential.get_token(*self._scopes)
  File "C:\Users\bulu\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\identity\_credentials\default.py", line 172, in get_token
    return super(DefaultAzureCredential, self).get_token(*scopes, **kwargs)
  File "C:\Users\bulu\AppData\Local\Programs\Python\Python310\lib\site-packages\azure\identity\_credentials\chained.py", line 108, in get_token
    raise ClientAuthenticationError(message=message)
azure.core.exceptions.ClientAuthenticationError: DefaultAzureCredential failed to retrieve a token from the included credentials.
Attempted credentials:
        EnvironmentCredential: Authentication failed: AADSTS500011: The resource principal named //management.azure.com was not found in the tenant named xxxx Mooncake. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.
Trace ID: xxxxxxxx-xxxx-xxxx-xxxx-9e130dbf7900
Correlation ID: xxxxxxxx-xxxx-xxxx-xxxx-46769c9e1e10
Timestamp: 2022-01-27 12:09:35Z
To mitigate this issue, please refer to the troubleshooting guidelines here at //aka.ms/azsdk/python/identity/defaultazurecredential/troubleshoot.

問題解決

從錯誤消息 //management.azure.com 得知問題是由於 AlertsManagementClient 中使用的 Resource Principal 為默認值,並沒有隨著指定 base_url 而修改為 

//management.chinacloudapi.cn/ 。 可以通過在構造  AlertsManagementClient 對象時候,指定 credential_scopes 為 ["//management.chinacloudapi.cn/.default"] 來緩解問題。

修改後的程式碼為:

# 修改前:
alertClient = AlertsManagementClient(credential,subscription_id,base_url="//management.chinacloudapi.cn/")

# 修改後:
alertClient = AlertsManagementClient(credential,subscription_id,base_url="//management.chinacloudapi.cn/",credential_scopes=["//management.chinacloudapi.cn/.default"])

PS: 當創建其他資源的Client對象,如果遇見相同的 Principal 問題,可以設定 credential_scopes 來解決問題。

完整可遠行的程式碼為:

# Import the needed credential and management objects from the libraries.
from azure.identity import DefaultAzureCredential
from azure.mgmt.alertsmanagement import AlertsManagementClient

# Acquire a credential object using CLI-based authentication.
credential = DefaultAzureCredential()
subscription_id = "a9dc7515-7692-4316-9ad4-762f383eec10"

# # 修改前:
# alertClient = AlertsManagementClient(credential,subscription_id,base_url="//management.chinacloudapi.cn/")
# 修改後:
alertClient = AlertsManagementClient(credential,subscription_id,base_url="//management.chinacloudapi.cn/",credential_scopes=["//management.chinacloudapi.cn/.default"])



rules = alertClient.smart_detector_alert_rules.list()
for rule in rules:
    print("Rule Name: " + rule.name)

運行結果:

參考資料

alertsmanagement Package ://docs.microsoft.com/en-us/python/api/azure-mgmt-alertsmanagement/azure.mgmt.alertsmanagement?view=azure-python