Azure Python SDK:'ServicePrincipalCredentials'对象没有属性'get_token'。

24

所以我有以下Python3脚本来列出所有虚拟机。

import os, json
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.resource import ResourceManagementClient, SubscriptionClient
from azure.common.credentials import ServicePrincipalCredentials

credentials = ServicePrincipalCredentials(
        client_id="xxx",
        secret="xxx",
        tenant="xxx"
        )

resource_client = ResourceManagementClient(credentials, "my-subscription")
compute_client = ComputeManagementClient(credentials, "my-subscription")
network_client = NetworkManagementClient(credentials, "my-subscription")

for vm in compute_client.virtual_machines.list_all():
    print("\tVM: {}".format(vm.name))

但出于某种原因,我收到了以下错误:

Traceback (most recent call last):
  File "/Users/me/a/azure-test.py", line 17, in <module>
    for vm in compute_client.virtual_machines.list_all():
...
  File "/usr/local/lib/python3.8/site-packages/azure/core/pipeline/policies/_authentication.py", line 93, in on_request
    self._token = self._credential.get_token(*self._scopes)
AttributeError: 'ServicePrincipalCredentials' object has no attribute 'get_token'

我做错了什么吗?

2个回答

48

为了共享常见的云模式,例如验证协议、日志记录、跟踪、传输协议、缓冲响应和重试,Azure Python 库目前正在更新中。

这也会稍微改变身份验证机制。在旧版本中,azure.common 中的 ServicePrincipalCredentials 用于对 Azure 进行身份验证并创建服务客户端。

在新版本中,身份验证机制已被重新设计并由 azure-identity 库取代,以基于 Azure Identity 为所有 Azure SDK 提供统一的身份验证。运行 pip install azure-identity 来获取该包。

在代码方面,那么原来是:

from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.compute import ComputeManagementClient

credentials = ServicePrincipalCredentials(
    client_id='xxxxx',
    secret='xxxxx',
    tenant='xxxxx'
)

compute_client = ComputeManagementClient(
    credentials=credentials,
    subscription_id=SUBSCRIPTION_ID
)

现在是:

from azure.identity import ClientSecretCredential
from azure.mgmt.compute import ComputeManagementClient

credential = ClientSecretCredential(
    tenant_id='xxxxx',
    client_id='xxxxx',
    client_secret='xxxxx'
)

compute_client = ComputeManagementClient(
    credential=credential,
    subscription_id=SUBSCRIPTION_ID
)
你可以使用 compute_client 中的 list_all 方法,像往常一样列出所有 VM:
# List all Virtual Machines in the specified subscription
def list_virtual_machines():
    for vm in compute_client.virtual_machines.list_all():
        print(vm.name)

list_virtual_machines()

参考文献:


4

在Azure主权云(AZURE_PUBLIC_CLOUDAZURE_CHINA_CLOUDAZURE_US_GOV_CLOUDAZURE_GERMAN_CLOUD)的情况下,已接受答案将扩展到以下代码片段。

from azure.identity import ClientSecretCredential
from azure.mgmt.compute import ComputeManagementClient
from msrestazure.azure_cloud import AZURE_US_GOV_CLOUD as cloud_env

credential = ClientSecretCredential(
    tenant_id='xxxxx',
    client_id='xxxxx',
    client_secret='xxxxx',
    authority=cloud_env.endpoints.active_directory
)

compute_client = ComputeManagementClient(
    credential=credential,
    subscription_id=SUBSCRIPTION_ID
    base_url=cloud_env.endpoints.resource_manager,
    credential_scopes=[cloud_env.endpoints.resource_manager + ".default"]
)

谢谢您指出这个问题!这拯救了我的一天,但 credential_scopes 必须得改正。它应该以斜杠结尾: credential_scopes=[cloud_env.endpoints.resource_manager + "/.default"] 否则我会收到以下错误信息: "azure.core.exceptions.ClientAuthenticationError: Authentication failed: AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid." - ralfzen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接