You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Batch中Python的ServicePrincipalCredentials等效C#实现问题

Azure Batch服务主体认证:Python转C#及问题解决

原Python认证代码

from azure.common.credentials import ServicePrincipalCredentials

creds = ServicePrincipalCredentials(
        client_id=AZURE_CLIENT_ID,
        secret=AZURE_CLIENT_SECRET,
        tenant=AZURE_CLIENT_TENANT,
        resource="https://batch.core.windows.net/")

尝试的C#实现及遇到的错误

方式一

var credential = new ClientSecretCredential(accountSettings.TenantId, accountSettings.ClientId, accountSettings.ClientSecret);
var token = await credential.GetTokenAsync(new TokenRequestContext(new[] { ".default" }));
var batchClient = new BatchServiceClient(new TokenCredentials(token.Token));

错误:调用CommitAsync()时返回 Operation returned an invalid status code 'Unauthorized'

方式二

var tokenCredentials = await ApplicationTokenProvider.LoginSilentAsync($"https://login.microsoftonline.com/{accountSettings.TenantId}", accountSettings.ClientId, accountSettings.ClientSecret);
var batchClient = new BatchServiceClient(tokenCredentials);

using (BatchClient client = BatchClient.Open(batchClient)) {...}

错误:调用CommitAsync()时同样返回 Operation returned an invalid status code 'Unauthorized'

方式三

var credential = new ClientCredential(accountSettings.ClientId, accountSettings.ClientSecret);
var authenticationContext = new AuthenticationContext($"https://login.microsoftonline.com/{accountSettings.TenantId}");
var result = await authenticationContext.AcquireTokenAsync("https://batch.core.windows.net/", credential);
var batchClient = new BatchServiceClient(new TokenCredentials(result.AccessToken));

错误:调用CommitAsync()时返回 Operation returned an invalid status code 'Unauthorized'

方式四

var credential = new ClientSecretCredential(accountSettings.TenantId, accountSettings.ClientId, accountSettings.ClientSecret);
var token = await credential.GetTokenAsync(new TokenRequestContext(new[] { $"https://batch.core.windows.net/.default" }));
var batchServiceClient = new BatchServiceClient(new TokenCredentials(token.Token));

错误:返回 Operation returned an invalid status code 'BadRequest',错误详情:

MissingRequiredProperty, Property=type, A required property was not specified in the request body.

调用栈:

at Microsoft.Azure.Batch.Protocol.PoolOperations.d__6.MoveNext()
at Microsoft.Azure.Batch.Protocol.BatchRequestBase`2.<ExecuteRequestWithCancellationAsync>d__42.MoveNext()
at Microsoft.Azure.Batch.Protocol.BatchRequestBase`2.d__40.MoveNext()

正确实现方案

以下是匹配原Python逻辑的有效C#代码,同时解决上述错误:

using Azure.Identity;
using Microsoft.Azure.Batch;

// 替换为你的批量账户信息
var tenantId = accountSettings.TenantId;
var clientId = accountSettings.ClientId;
var clientSecret = accountSettings.ClientSecret;
var batchAccountUrl = "https://<你的批量账户名>.<区域>.batch.azure.com/";

// 初始化服务主体凭证
var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);

// 打开Batch客户端连接(必须指定批量账户URL)
using var batchClient = BatchClient.Open(credential, batchAccountUrl);

// 示例:创建批量池
var pool = batchClient.PoolOperations.CreatePool(
    poolId: "sample-pool",
    targetDedicatedComputeNodes: 1,
    virtualMachineSize: "Standard_D2s_v3",
    cloudServiceConfiguration: new CloudServiceConfiguration(osFamily: "5"));

await pool.CommitAsync();

核心修复点

  1. 指定批量账户URL:所有错误的核心原因之一是未提供Batch账户的具体Endpoint,BatchClient需要明确知道要访问的批量服务地址。
  2. 权限验证:确保服务主体已被授予Azure Batch账户的Batch Account Contributor或同等权限,否则会持续出现Unauthorized错误。
  3. SDK版本适配:使用最新的Azure.Identity和Microsoft.Azure.Batch NuGet包,避免旧API的兼容性问题。
  4. 正确的凭证传递:通过BatchClient.Open直接传入ClientSecretCredential,无需手动获取Token再封装,SDK会自动处理Token的获取和刷新。

内容的提问来源于stack exchange,提问作者Eusebiu Marcu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 03:45:05