azure-sdk-for-net icon indicating copy to clipboard operation
azure-sdk-for-net copied to clipboard

[BUG] ##[error]ASPNETCOMPILER(0,0): Error ASPRUNTIME: Type is not resolved for member 'Azure.Identity.CredentialUnavailableException,Azure.Identity, Version=1.5.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8'.

Open tegrit-joe-trupiano opened this issue 3 years ago • 15 comments
trafficstars

Library name and version

Azure.Identity 1.5.0.0

Describe the bug

When using the build solution task in azure pipelines I get this error. If I remove /p:PrecompileBeforePublish=true from the build args it will build fine. Also if I remove the <connectionStrings configBuilders="AzureKeyVault"> from the web config it will build fine.

location --------------------- -azure devops -piplines -build solution task

ms build args---- /p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\" /p:PrecompileBeforePublish=true /p:UseMerge=true /p:SingleAssemblyName=CompiledViews

Expected behavior

Does not throw an error in the "Visual Studio build" task when using azure devops - pipelines

Actual behavior

thorws this error for every project that uses the azure.identity

##[error]ASPNETCOMPILER(0,0): Error ASPRUNTIME: Type is not resolved for member 'Azure.Identity.CredentialUnavailableException,Azure.Identity, Version=1.5.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8'.

Reproduction Steps

Set up a pipeline in azure devops that uses the 'Visual Studio build' task and build a project that uses keyvaults from the web config using these msbuild args

ms build args---- /p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\" /p:PrecompileBeforePublish=true /p:UseMerge=true /p:SingleAssemblyName=CompiledViews

Environment

Windows 10 .Net Framework 4.7.2 Microsoft Visual Studio Enterprise 2019-Version 16.11.11 Azure devops Pipeline

tegrit-joe-trupiano avatar Apr 30 '22 18:04 tegrit-joe-trupiano

Thank you for your feedback. Tagging and routing to the team members best able to assist.

jsquire avatar May 02 '22 12:05 jsquire

@tegrit-joe-trupiano Are you able to figure out the problem? Please share fix details.

Saurabhsrikant avatar Jul 28 '22 22:07 Saurabhsrikant

@tegrit-joe-trupiano Are you able to figure out the problem? Please share fix details.

I did not, Sorry

Also just updated to 1.6 and still get the same error!

tegrit-joe-trupiano avatar Jul 29 '22 18:07 tegrit-joe-trupiano

@tegrit-joe-trupiano Any update?

42jdg avatar Oct 20 '22 14:10 42jdg

Hi @tegrit-joe-trupiano - This issue looks similar, do any of the workarounds or suggestions there work for you? #17216

christothes avatar Oct 21 '22 17:10 christothes

@tegrit-joe-trupiano Any update?

Nope nothing yet

tegrit-joe-trupiano avatar Oct 21 '22 17:10 tegrit-joe-trupiano

Hi @tegrit-joe-trupiano - This issue looks similar, do any of the workarounds or suggestions there work for you? #17216

None of the work arounds worked for me as we are using devops/piplelines. I opened this issue because 17216 was closed and nothing in it was helpful for my case.

tegrit-joe-trupiano avatar Oct 21 '22 17:10 tegrit-joe-trupiano

@tegrit-joe-trupiano - Is it possible that the build is either finding an older version of Azure.Identiy, or cannot find it at all? Does you build output show which version is being found?

christothes avatar Oct 28 '22 20:10 christothes

@tegrit-joe-trupiano - Is it possible that the build is either finding an older version of Azure.Identiy, or cannot find it at all? Does you build output show which version is being found?

It only happens when ms build arg p:PrecompileBeforePublish=true. I had to disable this param for every build and it slows down our production sites on startup without it.

tegrit-joe-trupiano avatar Oct 29 '22 00:10 tegrit-joe-trupiano

@tegrit-joe-trupiano - Is it possible that the build is either finding an older version of Azure.Identiy, or cannot find it at all? Does you build output show which version is being found?

It only happens when ms build arg p:PrecompileBeforePublish=true. I had to disable this param for every build and it slows down our production sites on startup without it.

Understood - but I'm curious which version of Azure.Identity your build is resolving in that case.

christothes avatar Oct 31 '22 14:10 christothes

@tegrit-joe-trupiano - Is it possible that the build is either finding an older version of Azure.Identiy, or cannot find it at all? Does you build output show which version is being found?

It only happens when ms build arg p:PrecompileBeforePublish=true. I had to disable this param for every build and it slows down our production sites on startup without it.

Understood - but I'm curious which version of Azure.Identity your build is resolving in that case.

we have since updated to 1.6.0. This is what we get from the build process

--NUGET RESTORE-- Restoring NuGet package Azure.Identity.1.6.0. Adding package 'Azure.Identity.1.6.0' to folder 'C:\AZAgent\Agent6_work\9\s\Development\packages'

Added package 'Azure.Identity.1.6.0' to folder 'C:\AZAgent\Agent6_work\9\s\Development\packages' Added package 'Azure.Identity.1.6.0' to folder 'C:\AZAgent\Agent6_work\9\s\Development\packages' from source 'C:\Windows\ServiceProfiles\NetworkService.nuget\packages'

--BUILD SOLUTION-- Copying file from "C:\AZAgent\Agent6_work\9\s\Development\packages\Azure.Identity.1.6.0\lib\netstandard2.0\Azure.Identity.dll"

We get this about ~20 times in the build with all showing

--ERROR-- AspNetPreCompile: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_compiler.exe -v / -p C:\AZAgent\Agent6_work\9\s\Development*\obj\x64*\AspnetCompileMerge\Source -c C:\AZAgent\Agent6_work\9\s\Development*\obj\x64*\AspnetCompileMerge\TempBuildDir ##[error]ASPNETCOMPILER(0,0): Error ASPRUNTIME: Type is not resolved for member 'Azure.Identity.CredentialUnavailableException,Azure.Identity, Version=1.6.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8'. 26>ASPNETCOMPILER : error ASPRUNTIME: Type is not resolved for member

tegrit-joe-trupiano avatar Oct 31 '22 15:10 tegrit-joe-trupiano

Can you confirm that you are unable to reproduce the error with the same build command locally (with the paths fixed up to be correct for local)?

christothes avatar Oct 31 '22 16:10 christothes

Can you confirm that you are unable to reproduce the error with the same build command locally (with the paths fixed up to be correct for local)?

I just tested this and Yes I still get the same error locally running the same command from developer command prompt

tegrit-joe-trupiano avatar Oct 31 '22 16:10 tegrit-joe-trupiano

Hi, we're sending this friendly reminder because we haven't heard back from you in 7 days. We need more information about this issue to help address it. Please be sure to give us your input. If we don't hear back from you within 14 days of this comment the issue will be automatically closed. Thank you!

ghost avatar Nov 08 '22 08:11 ghost

@tegrit-joe-trupiano At least in my case, It looks like the process needs to connect to Azure, but it doesn't connect using TLS1.2 I apply the suggested changes to the windows registry: https://learn.microsoft.com/en-us/dotnet/framework/network-programming/tls After this, the compilation was successful without the parameter "/p:PrecompileBeforePublish=true"

Additionally, I added the enviroment's variables AZURE_CLIENT_ID, AZURE_CLIENT_SERCRET, and AZURE_TENANT_ID (added to my pipeline variables)

42jdg avatar Nov 11 '22 08:11 42jdg

@tegrit-joe-trupiano At least in my case, It looks like the process needs to connect to Azure, but it doesn't connect using TLS1.2 I apply the suggested changes to the windows registry: https://learn.microsoft.com/en-us/dotnet/framework/network-programming/tls After this, the compilation was successful without the parameter "/p:PrecompileBeforePublish=true"

Additionally, I added the enviroment's variables AZURE_CLIENT_ID, AZURE_CLIENT_SERCRET, and AZURE_TENANT_ID (added to my pipeline variables)

Hi, looks like adding the environment variables for key vault to the pipeline variables did the trick. I was 99% sure I had already tried that, but I guess not. Thanks for the help!

tegrit-joe-trupiano avatar Nov 11 '22 23:11 tegrit-joe-trupiano

The exact problem happens to me within Visual Studio 2019 and 2022 publishing with precompiling enabled. The registry update didn't fix it. I have been revisiting the problem for months, updating libraries, to no avail. Again, if I turn off precompiling, it works. Setting azure keys in environment variables of development machines is off the question for obvious reasons.

grammophone avatar Nov 21 '22 17:11 grammophone

I have crafted a different workaround that doesn't require sensitive keys circulating in environment variables. Disclaimer: It is very dirty, use at your own discretion, but this is the only option apart from building our own ConfigurationBuilder from scratch, until Microsoft fixes this. My setup is the precompiler running inside Visual Studio's deployment, but I believe it will run in Azure Pipelines as well. We subclass the AzureKeyVaultConfigBuilder class and we override its LazyInitialize method, where we catch the CredentialUnavailableException, which is caused by the base class's effort to open a KeyVault client there. We sniff whether it was thrown inside the precompiler, and if so, we swallow it, otherwise we re-throw it. If the exception didn't occur, we mark that the class is initialized as intended. We override GetValue and GetAllValues methods to provide mock implementations if the class hasn't yet reached a complete initialization.

This is the code implementing the above idea when using version 2.0 of the Microsoft.Configuration.ConfigurationBuilders.Azure library:

public class LazyAzureKeyVaultConfigBuilder : AzureKeyVaultConfigBuilder
{
  private bool isInitialized;

  private readonly IDictionary<string, string> valuesByKey;

  public LazyAzureKeyVaultConfigBuilder()
  {
    isInitialized = false;

    valuesByKey = new Dictionary<string, string>();
  }

  protected override void LazyInitialize(string name, NameValueCollection config)
  {
    try
    {
      base.LazyInitialize(name, config);
    }
    catch (Azure.Identity.CredentialUnavailableException)
    {
      // Test if inside precompiler...
      // (If the Azure Pipelines has a different process name, change "aspnet_compiler". Or...
      // ... conversely test against your own deployed app name instead.)
      if (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "aspnet_compiler")
      {
        // Do nothing. Try to initialize again after each failure.
        return;
      }
      else
      {
        throw;
      }
    }

    isInitialized = true;
  }

  public override string GetValue(string key)
  {
    if (String.IsNullOrWhiteSpace(key)) return String.Empty;

    if (!isInitialized)
    {
      if (valuesByKey.TryGetValue(key, out string value))
      {
        return value;
      }
      else
      {
        return String.Empty;
      }
    }
    else
    {
      return base.GetValue(key);
    }
  }

  public override ICollection<KeyValuePair<string, string>> GetAllValues(string prefix)
  {
    if (!isInitialized)
    {
      return valuesByKey;
    }
    else
    {
      return base.GetAllValues(prefix);
    }
  }
}

Use this subclass as your config builder in your config file the usual way:

<configBuilders>
  <builders>
  <add name="AzureKeyVault" vaultName="${keyVaultName}"
       type="MyApp.Web.Configuration.LazyAzureKeyVaultConfigBuilder, MyApp.Web" />
  </builders>
</configBuilders>

grammophone avatar Jan 12 '23 14:01 grammophone