在使用python sdk 登录到AzureChinaCloud时常遇到”azure.core.exceptions.ClientAuthenticationError: Authentication failed: AADSTS500011 The resource principal named https://management.azure.com was not found“这个错误。
源代码如下:
from azure.mgmt.containerservice import ContainerServiceClient
from azure.identity import ClientSecretCredential
credential = ClientSecretCredential(tenant_id='*******',
client_id='********',
client_secret='**********',
)
client = ContainerServiceClient(credential, subscription_id='*****')
cluster = client.managed_clusters.get(resource_name='****', resource_group_name='****')
print(cluster)
通过查阅源码可知:
默认验证方式为Azure Public Cloud,若想访问AzureChinaCloud 我们需要从azure.identity包中导入AzureAuthorityHosts这个类。
引入后代码如下
credential = ClientSecretCredential(tenant_id='*******',
client_id='********',
client_secret='**********',
authority=AzureAuthorityHosts.AZURE_CHINA
)
在此测试仍然报相同的错误,有了上一步的经验,我们将鼠标移动到ContainerServiceClient这个类中,可以看到有一个base_url参数,默认是Azure Public Cloud的 ResourceManager的url,我们需要在构建参数时给他指定中国区的base_url: 'https://management.chinacloudapi.cn',源码如下:
修改我们的代码为:
client = ContainerServiceClient(credential, subscription_id='*****',
base_url='https://management.chinacloudapi.cn',
)
运行发现仍然报相同错误,我们知道token用来访问资源,而AzureChinaCloud中 TokenCredential 是众多Token验证的父类之一,在TokenCredential中,有一个get_token方法,需要指明scope,我们怀揣此想法点开ContainerServiceClient这个类,发现没有指定Scope的变量的参数,但是发现他在init方法中调用了ContainerServiceClientConfiguration这个类,我们点开这个类,果然在他的init方法中发现了获取scope的方法,若没有提供则默认获取Azure Public Cloud的scope,截图如下:
TokenCredential源码:
ContainerServiceClient源码,(init 方法中调用了ContainerServiceClientConfiguration):
点开ContainerServiceClientConfiguration,可以看到在源码中,如果未给变量赋值,则默认获取Azure Public Cloud的Resource Manager的url。
了解错误原因后,接下来就简单了,我们在创建ContainerServiceClient时,给他指定scope:
client = ContainerServiceClient(credential, subscription_id='**************',
base_url='https://management.chinacloudapi.cn',
credential_scopes=["https://management.chinacloudapi.cn/.default"])
指定完后,就可以在控制台中发现获取到了资源。