在Azure DevOps构建流程中使用托管标识

12

我成功地使用以下代码(完整代码在此处)来使用 Azure 托管标识进行身份验证(通过 Visual Studio),并且可以访问 Azure 存储账户,而无需使用凭据。

const string storageResource = "https://storage.azure.com/";

var authResult = await azureServiceTokenProvider.GetAuthenticationResultAsync(storageResource, cancellationToken: cancellationToken);

这段代码成功找到了我登录到Visual Studio的用户,并使用它来获取令牌,一切顺利。

然而,此代码作为库集成测试的一部分在Azure DevOps构建管道中执行。

我在创建与Azure DevOps的服务连接时发现了创建的服务主体,并为其授予了相同的Storage Blob数据参与者角色,希望Azure DevOps会使用它来运行代码,但没有成功。

所以我的问题是:

如何让在Azure DevOps构建管道中运行的代码能够使用AzureServiceTokenProvider进行身份验证?

顺便说一句,错误消息如下:

Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException :参数:连接字符串:[未指定连接字符串],资源:https://storage.azure.com/,权限:。 异常消息:尝试以下3种方法来获取访问令牌,但均未成功。 参数:连接字符串:[未指定连接字符串],资源:https://storage.azure.com/,权限:。 异常消息:尝试使用托管服务标识获取令牌。无法获取访问令牌。重试5次后失败。 MSI响应代码:BadRequest,响应: {"error":"invalid_request","error_description":"Identity not found"} 参数:连接字符串:[未指定连接字符串], 资源:https://storage.azure.com/,权限:。 异常消息:尝试使用Visual Studio获取令牌。无法获取访问令牌。在 "C:\Users\VssAdministrator\AppData\Local.IdentityService\AzureServiceAuth\tokenprovider.json"中找不到Visual Studio Token提供程序文件 参数:连接字符串:[未指定连接字符串], 资源:https://storage.azure.com/,权限:。 异常消息:尝试使用Azure CLI获取令牌。无法获取访问令牌。错误:请运行'az login'来设置帐户。

TearDown:System.NullReferenceException:对象引用未设置为对象的实例。


你能找到这个问题的答案吗?我也遇到了同样的问题。 - JsAndDotNet
@HockeyJ,非常抱歉,我现在不记得问题是什么了。 - Fabio Milheiro
3个回答

13

在Azure DevOps中创建服务连接时,你会看到(截至目前)4个选项。

  • 服务主体(也称为Azure Active Directory中的应用程序注册)
  • 管理标识
  • 发布配置文件

New Azure service connection

一个发布配置文件是Azure App Service特定的身份验证机制,可以通过Kudu进行发布。
管理身份有些名称不当。它们用于允许运行您的Azure管道的虚拟机作为该VM的托管身份(然后您将此托管身份授予访问Azure门户中要访问的资源)。这与其他身份验证方法的工作方式相反,但我想在Azure VM上托管自己的Azure管道时,这是有意义的。此选项具有此注意事项。
AzureServiceTokenProvider仅适用于公开MSI_ENDPOINT(又名IDENTITY_ENDPOINT)的环境内部。托管的Azure DevOps管道不属于这种环境。
服务主体是您可能会使用的内容。
服务主体有两种类型:自动和手动。再次提醒命名不当。实际上,自动选项没有任何自动功能,它只是为您在Azure AD中提供服务主体。它将在订阅级别上授予服务主体“参与者角色”(这意味着除了访问控制之外,可以完全访问订阅中的所有内容)。您不应授予服务主体这种访问权限。这是过度的。请记住,您的服务主体只受凭据保护,如果凭据泄漏,它们会允许任何人造成不可挽回的损害。

你的回答似乎没有从安全角度提供好的解决方案。在 DevOps Build Pipeline 中,一个具有 SQL Server 访问权限的托管标识是否无法被 XUnit 项目调用? - J Weezy
1
@JWeezy 你可以设置自己的 VM 并配备托管标识。在此计算机上运行的构建将作为托管标识进行身份验证。然后,您可以授予托管标识访问 SQL Azure 的权限。从安全角度来看,问题转移到了 VM 上,任何可以访问此 VM 或将构建排队到此 VM 的人基本上都可以访问相同的资源。另一种选择是创建服务主体并将客户端密钥放入密钥保管库中。然后,您通过密钥保管库管理对此秘密的访问方式就是保护您的身份的方法。 - John Leidegren
谢谢解释。但是服务主体是否可用于此目的?也就是说,它能否提供给在构建中运行的代码(而不是专门设计为接受服务连接的步骤)? - Jan Hudec
这个工作原理是,一旦你建立了连接,就可以使用 az CLI 工具来执行操作或从该环境中获取访问令牌。这些访问令牌将被分配给服务主体,并具有与服务主体相同的访问权限。这就好像你使用服务主体作为登录方式登录 Azure 门户一样。 - John Leidegren

1

由于目前还没有回答这个问题,您可以尝试以下操作: 尝试将连接信息明确传递给 azureServiceTokenProvider。现在,以下代码块假定您正在使用 共享密钥凭据登录到 Azure AD,但可以扩展到此处描述的任何方法 - 使用.NET进行与Azure Key Vault的服务对服务身份验证

var azureServicesAuthString = $"RunAs=App;AppId={AppId};TenantId={TenantId};AppKey={ClientSecret}";
tokenProvider = new AzureServiceTokenProvider(connectionString: azureServicesAuthString);
var authResult = await azureServiceTokenProvider.GetAuthenticationResultAsync(storageResource, cancellationToken: cancellationToken);

-2
您需要创建一个类型为 "托管标识认证" 的服务连接,以在 DevOps 流水线中使用托管标识。

它只适用于基于VM的代理,而不适用于托管代理。 - Thomas
1
还不太清楚。创建了一个类型为“托管标识身份验证”的服务连接后,我除了连接名称之外没有其他选择。然后我尝试在Azure门户中查找托管标识,但什么也没找到。我仍然不明白如何使构建机器能够使用令牌提供程序进行身份验证的要点。@Thomas建议托管代理目前还无法像这样进行身份验证,但我甚至不确定是否拥有自己的VM来构建。 - Fabio Milheiro
只是为了明确,我知道如何创建自己的构建服务器并让Azure DevOps选择它们进行构建。只是创建“托管标识身份验证”似乎没有任何作用。显然,我还是迷失了方向,但欢迎任何指针。谢谢@Varun和Thomas。 - Fabio Milheiro
据我所知,这是在运行管道的虚拟机上启用系统分配的托管标识,这就是为什么您无法在 AAD 中找到它的原因。您需要授予虚拟机本身对存储帐户的访问权限。 - Igor

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