通过自定义脚本中的 Azure DevOps 的“az login”进行身份验证

问题描述 投票:0回答:2

我正在尝试创建一个 python 脚本来与 Azure DevOps 交互,但在身份验证方面遇到问题。我不想使用 PAT。当我尝试使用

DefaultAzureCredential
中的
azure.identity
时,出现以下错误: “DefaultAzureCredential”对象没有属性“signed_session”

from azure.identity import DefaultAzureCredential
from azure.devops.connection import Connection

credential = DefaultAzureCredential()
connection = Connection(base_url="https://dev.azure.com/org_name", creds=credential)
core_client = connection.clients.get_core_client()
projects = core_client.get_projects()

我找到了另一种方法。这有效,但我注意到建议使用

azure.identity
而不是
azure.common.credentials.get_azure_cli_credentials()

from azure.common.credentials import get_azure_cli_credentials
from azure.devops.connection import Connection

credential = get_azure_cli_credentials()[0]
connection = Connection(base_url="https://dev.azure.com/org_name", creds=credential)
core_client = connection.clients.get_core_client()
projects = core_client.get_projects()

我做错了什么

azure.identity
还是有更好的方法?

python azure-devops azure-devops-rest-api
2个回答
2
投票

我有一个名为

sridevOpsdemo
的 Azure DevOps 组织,包含以下项目:

enter image description here

当我运行与你相同的Python代码来列出项目时,我得到了同样的错误

from azure.identity import DefaultAzureCredential
from azure.devops.connection import Connection

credential = DefaultAzureCredential()
connection = Connection(base_url="https://dev.azure.com/org_name", creds=credential)
core_client = connection.clients.get_core_client()
projects = core_client.get_projects()

回复:

enter image description here

或者,您可以为 DevOps 生成 Azure AD 访问令牌 如果您不想使用 PAT 令牌,请使用 API。

我注册了一个 Azure AD 应用程序并授予了 同意 DevOps 权限:

enter image description here

现在,我通过运行下面的 python 代码使用用户名密码流程生成了访问令牌

import msal
import requests

organization_url = "https://dev.azure.com/org_name/"

tenant_id = "tenant_id"
client_id = "app_id"

username = "[email protected]"
password = "xxxxxxxx"

scopes = ["499b84ac-1321-427f-aa17-267ca6975798/.default"]

authority = f"https://login.microsoftonline.com/{tenant_id}"

app = msal.PublicClientApplication(client_id=client_id, authority=authority)

result = app.acquire_token_by_username_password(
    username=username,
    password=password,
    scopes=scopes,
)

if "error" in result:
    print(f"Authentication error: {result['error']}")

else:
    access_token = result.get("access_token")
    print(access_token)

回复:

enter image description here

确认,您可以通过将上述令牌粘贴到jwt.ms中来解码并检查

aud
scp
声明,如下所示:

enter image description here

您可以通过修改代码中的api_url,使用上述访问令牌调用任何

DevOps REST API
查询,如下所示:

import msal
import requests

organization_url = "https://dev.azure.com/org_name/"

tenant_id = "tenant_id"
client_id = "app_id"

username = "[email protected]"
password = "xxxxxxxx"

scopes = ["499b84ac-1321-427f-aa17-267ca6975798/.default"]

authority = f"https://login.microsoftonline.com/{tenant_id}"

app = msal.PublicClientApplication(client_id=client_id, authority=authority)

result = app.acquire_token_by_username_password(
    username=username,
    password=password,
    scopes=scopes,
)

if "error" in result:
    print(f"Authentication error: {result['error']}")

else:
    access_token = result.get("access_token")
    print(access_token)
    
    headers = {
        'Authorization': f'Bearer {access_token}'
    }

    # List all projects in organization
    api_url = f"{organization_url}/_apis/projects"
    response = requests.get(api_url, headers=headers)

    if response.status_code == 200:
        projects = response.json()['value']
        print("\nProject Names:")
        for project in projects:
            print(project['name'])
        print()

    else:
        print(f"Failed to retrieve projects. Status Code: {response.status_code}, Message: {response.text}")

回复:

enter image description here

参考: 无需用户的 DevOps PAT 即可对 Azure DevOps 进行身份验证 - Stack Overflow,作者:wade Zhou - MSFT


0
投票

我注意到在一些地方(az devops CLI 扩展Azure SDK for Pythonaz CLI)使用了

msrest
库。该库被标记为已弃用,但如果 Microsoft 使用它,我认为使用它是有意义的,直到通过 Azure DevOps SDK 可以使用 DefaultAzureCredential。我设法通过将令牌从 msrest.authentication 传递到 BasicTokenAuthentication 来创建一个凭据对象。

from azure.identity import DefaultAzureCredential
from msrest.authentication import BasicTokenAuthentication
from azure.devops.connection import Connection

credential = DefaultAzureCredential()
token = credential.get_token('499b84ac-1321-427f-aa17-267ca6975798/.default')
credentials = BasicTokenAuthentication({'access_token': token.token})
organization_url = 'https://dev.azure.com/myorg'
connection = Connection(base_url=organization_url, creds=credentials)

core_client = connection.clients.get_core_client()
get_projects_response = core_client.get_projects()
if get_projects_response:
    for project in get_projects_response:
        print(project.name)

输出:

myproject

当 PAT 替换为令牌时,使用 PAT 的文档中的示例也适用

© www.soinside.com 2019 - 2024. All rights reserved.