C# VSTS生成管道:测试无法连接到Azure密钥库

C# VSTS生成管道:测试无法连接到Azure密钥库,c#,asp.net,azure,azure-devops,azure-pipelines,C#,Asp.net,Azure,Azure Devops,Azure Pipelines,我正在尝试使用VST(现在的Azure DevOps)来执行CI/CD管道。对于我的构建管道,我有一个非常基本的设置,包括执行恢复、构建、测试和发布步骤 对于我的测试步骤,我将其设置为运行两个测试项目——一个单元测试项目和一个集成测试项目。我已设置了密钥保管库访问策略,以提供对我自己和Azure Devops的访问。当我使用visual studio在本地运行测试时,由于我已登录到具有azure key vault访问权限的同一帐户,因此我可以运行测试而不会出现任何错误 我的应用程序配置为使用以

我正在尝试使用VST(现在的Azure DevOps)来执行CI/CD管道。对于我的构建管道,我有一个非常基本的设置,包括执行恢复、构建、测试和发布步骤

对于我的测试步骤,我将其设置为运行两个测试项目——一个单元测试项目和一个集成测试项目。我已设置了密钥保管库访问策略,以提供对我自己和Azure Devops的访问。当我使用visual studio在本地运行测试时,由于我已登录到具有azure key vault访问权限的同一帐户,因此我可以运行测试而不会出现任何错误

我的应用程序配置为使用以下设置访问密钥库:

 public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((ctx, builder) =>
            {
                var keyVaultEndpoint = GetKeyVaultEndpoint();

                if (!string.IsNullOrEmpty(keyVaultEndpoint))
                {
                    var azureServiceTokenProvider = new AzureServiceTokenProvider();
                    var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
                    builder.AddAzureKeyVault(keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager());
                }
            }
        )
            .UseStartup<Startup>();

更新 我只找到了1篇与此问题相关的帖子:。但这篇文章与将应用程序部署到azure插槽有关。我只是尝试在构建管道中构建我的应用程序

我仍在努力解决这个问题,不确定提供所需访问的最佳方式是什么


更新2 我还没有找到解决这个问题的办法。我不知道如何让我的管道毫无问题地运行测试。我看到发布管道中也有运行测试的选项。但是这些文件似乎包含.dll文件,而我的构建管道放置文件只有web应用程序(我没有看到任何发布的测试项目放置文件)。不确定这是否有可能


更新3 通过使用此处提供的最后一个选项,我成功地使其工作:

我尝试了使用证书的其他方法,但只要连接字符串中提供了{CurrentUser},构建管道就会失败。它在本地机器上工作,但在构建管道中不工作

为了让它发挥作用,我必须做三件事:

  • 登录到Azure。在Azure AD中设置新的应用程序注册
  • 在新的广告应用注册中,创建新的客户端密码
  • 为新的广告应用程序提供访问密钥库的权限。进入您的密钥库访问策略,并添加您在广告中创建的应用程序,该应用程序对您的机密具有读取权限。

  • 在myProgram.cs文件中修改了对AzureServiceTokenProvider()的调用,如下所示:

     var azureServiceTokenProvider = new AzureServiceTokenProvider("connectionString={your key vault endpoint};RunAs=App;AppId={your app id that you setup in Azure AD};TenantId={your azure subscription};AppKey={your client secret key}")
    
请注意,您的客户端密码必须正确格式化。应用程序注册(预览)生成一个随机密钥。有时,此键在连接字符串中不起作用(由于格式不正确而引发错误)。请尝试在应用程序注册的非预览版本中生成您自己的密钥,或者生成新密钥并重试

之后,我能够在我的构建管道中成功运行集成测试,并在Azure中为我的web应用程序创建一个版本。我对这种方法不满意,因为尽管它有效,但它在代码本身中暴露了一个秘密值。由于上述方法,不需要打开管理服务标识。我觉得这是非常糟糕的


一定有比这更好的办法。一个选项是不在构建管道中运行集成测试。不确定这是否是正确的方法。我仍然希望有人能够提供更好的方法,或者解释我的方法是否可以使用

我自己也遇到了同样的问题。通过向AzureServiceTokenProvider添加一个连接字符串(传递的默认参数为null),我对代码进行了进一步修改。尽管如此,我仍然没有让它完全发挥作用,可能是因为Azure DevOps用户可能有或可能没有访问KeyVault所需的权限,但我没有得到进一步挖掘的机会。 希望有一个更好的解决方案张贴在这里

更新
我们将构建用户添加到Azure AD中,然后将其添加到KeyVault中的访问策略中。只授予它访问权限(我们的测试只是测试它是否能够收集秘密)。测试现在已成功通过。

您不应该在Azure DevOps Pipelines build中对Azure KeyVault进行身份验证集成测试,因为您使用的是Azure DevOps默认托管代理

默认情况下,Azure DevOps管道使用基本的默认托管代理,这些托管代理无法从Azure订阅访问。这并不奇怪,因为这些托管代理是所有常见构建需求的通用代理,包括构建/编译、运行单元测试、获取测试覆盖率,并且所有这些任务都没有其他附加功能,例如拥有ActiveDirectory、数据库、,以及对其他方的其他实际身份验证/请求,如对任何Azure Keyvault的身份验证。因此,默认情况下,这些代理未在Azure订阅中注册

如果您希望针对这些特殊需求进行成功的集成测试,您必须为Azure DevOps管道构建和发布创建自己的代理。因此,除了创建您自己的代理并将Azure DevOps配置为使用您自己的代理之外,没有其他方法强制Azure DevOps默认代理运行您的KeyVault身份验证测试

要创建自己的代理,请参阅Microsoft的以下文档:

2018年10月29日更新

为了更清楚,我还回复了您的“更新3”解决方案。当Microsoft更新Azure DevOps的默认托管代理时,无法保证您的解决方案能够正常工作。 因此,我还需要补充一点:在Azure DevOps管道构建领域之外进行依赖于其他方的集成测试(例如连接到数据库服务器或在CI中使用外部身份验证(甚至在Azure KeyVault上)不是一个好做法,特别是当您使用Microsoft的默认托管代理时

由于身份验证配置无效,它不仅容易出错,而且无法保证默认托管代理上的进一步更新将保证您的第三方逻辑测试正常运行。

使用 var azureServiceTokenProvider = new AzureServiceTokenProvider("connectionString={your key vault endpoint};RunAs=App;AppId={your app id that you setup in Azure AD};TenantId={your azure subscription};AppKey={your client secret key}")
- task: AzureCLI@1
  inputs:
    azureSubscription: 'Your Service Connection Name'
    scriptLocation: 'inlineScript'
    inlineScript: 'dotnet test --configuration $(buildConfiguration) --logger trx'