Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DefaultAzureCredentials fails while working with ManagedIdentity in Visual Studio 2019 (.Net Core 3.1) #13228

Closed
spmanjunath opened this issue Jul 5, 2020 · 14 comments
Assignees
Labels
Azure.Identity bug This issue requires a change to an existing behavior in the product in order to be resolved. Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. needs-author-feedback Workflow: More information is needed from author to address the issue.
Milestone

Comments

@spmanjunath
Copy link

spmanjunath commented Jul 5, 2020

Describe the bug
I am using Azure.Identity 1.2.0-Preview.4 to access the StorageAccount from .Net Core 3.1 (from Visual Studio 2019), I have signed-in to VS2019 using the same Microsoft account as my Azure subscription where i am owner.

The code used to access storage account is:

var blobServiceClient = new BlobServiceClient(accountUri, new DefaultAzureCredential());
BlobContainerClient containerClient = await blobServiceClient.CreateBlobContainerAsync("media");
var blobClient = containerClient.GetBlobClient(fileName);
await blobClient.UploadAsync(stream, true);

When i run the code below exception is thrown:

DefaultAzureCredential authentication failed.
	SharedTokenCacheCredential authentication failed.   at Azure.Identity.SharedTokenCacheCredential.<GetTokenImplAsync>d__16.MoveNext()
	   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
	   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
	   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
	   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
	   at System.Threading.Tasks.ValueTask`1.get_Result()
	   at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult()
	   at Azure.Identity.SharedTokenCacheCredential.<GetTokenAsync>d__15.MoveNext()
	   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
	   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
	   at Azure.Identity.DefaultAzureCredential.<GetTokenFromSourcesAsync>d__12.MoveNext()
	   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
	   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
	   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
	   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
	   at System.Threading.Tasks.ValueTask`1.get_Result()
	   at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult()
	   at Azure.Identity.DefaultAzureCredential.<GetTokenImplAsync>d__11.MoveNext()   
		   AADSTS70002: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908.
			Trace ID: 1ba0333d-b37e-46c1-a2cb-5e61f26c8b01
			Correlation ID: d1b813c0-c50a-46df-a1d5-f2bd403273a6
			Timestamp: 2020-07-03 17:30:52Z
			
			   at Microsoft.Identity.Client.OAuth2.OAuth2Client.CreateErrorResponse(HttpResponse response, RequestContext requestContext)
		   at Microsoft.Identity.Client.OAuth2.OAuth2Client.CreateResponse[T](HttpResponse response, RequestContext requestContext, Boolean addCorrelationId)
		   at Microsoft.Identity.Client.OAuth2.OAuth2Client.<ExecuteRequestAsync>d__10`1.MoveNext()
		   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
		   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
		   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
		   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
		   at Microsoft.Identity.Client.OAuth2.OAuth2Client.<GetTokenAsync>d__9.MoveNext()
		   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
		   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
		   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
		   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
		   at Microsoft.Identity.Client.Internal.Requests.RequestBase.<SendHttpMessageAsync>d__22.MoveNext()
		   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
		   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
		   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
		   at Microsoft.Identity.Client.Internal.Requests.RequestBase.<SendTokenRequestAsync>d__21.MoveNext()
		   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
		   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
		   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
		   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
		   at Microsoft.Identity.Client.Internal.Requests.SilentRequest.<RefreshAccessTokenAsync>d__8.MoveNext()
		   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
		   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
		   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
		   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
		   at Microsoft.Identity.Client.Internal.Requests.SilentRequest.<TryGetTokenUsingFociAsync>d__7.MoveNext()
		   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
		   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
		   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
		   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
		   at Microsoft.Identity.Client.Internal.Requests.SilentRequest.<ExecuteAsync>d__6.MoveNext()
		   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
		   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
		   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
		   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
		   at Microsoft.Identity.Client.Internal.Requests.RequestBase.<RunAsync>d__14.MoveNext()
		   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
		   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
		   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
		   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
		   at Microsoft.Identity.Client.ApiConfig.Executors.ClientApplicationBaseExecutor.<ExecuteAsync>d__2.MoveNext()
		   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
		   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
		   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
		   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
		   at Azure.Identity.AbstractAcquireTokenParameterBuilderExtensions.<ExecuteAsync>d__0`1.MoveNext()
		   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
		   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
		   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
		   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
		   at Azure.Identity.MsalPublicClient.<AcquireTokenSilentAsync>d__5.MoveNext()
		   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
		   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
		   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
		   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
		   at Azure.Identity.SharedTokenCacheCredential.<GetTokenImplAsync>d__16.MoveNext()

I have tried following workarounds without success:

  • Ensured VS uses only one account
  • Azure CLI is signed-in with same account as that of Subscription and VS

I am unable to determine how else to fix this issue in my development environment, the StorageAccount in the subscription is enabled for Identity access.

@ghost ghost added needs-triage Workflow: This is a new issue that needs to be triaged to the appropriate team. customer-reported Issues that are reported by GitHub users external to the Azure organization. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that labels Jul 5, 2020
@jsquire jsquire added Azure.Identity Client This issue points to a problem in the data-plane of the library. needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team labels Jul 6, 2020
@ghost ghost removed the needs-triage Workflow: This is a new issue that needs to be triaged to the appropriate team. label Jul 6, 2020
@schaabs
Copy link
Contributor

schaabs commented Jul 8, 2020

@spmanjunath thanks for trying our preview and filing this issue. I'm investigating this now, and I'll update the issue once I have more information.

One thing you might try as a work-around is disabling the SharedTokenCacheCredential in the DefaultAzureCredential you're creating. Disabling this credential will allow the DefaultAzureCredential to fall back to the VisualStudioCredential which uses a legacy means of authenticating via Visual Studio.

var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ExcludeSharedTokenCacheCredential = true });

var blobServiceClient = new BlobServiceClient(accountUri, credential);

@AlexGhiondea AlexGhiondea added this to the [2020] August milestone Jul 23, 2020
@schaabs schaabs removed needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team question The issue doesn't require a change to the product in order to be resolved. Most issues start as that labels Jul 31, 2020
@jsquire jsquire added question The issue doesn't require a change to the product in order to be resolved. Most issues start as that bug This issue requires a change to an existing behavior in the product in order to be resolved. and removed question The issue doesn't require a change to the product in order to be resolved. Most issues start as that labels Aug 3, 2020
@schaabs
Copy link
Contributor

schaabs commented Nov 9, 2020

Just to give an update on this issue. The underlying issue here is that MSA accounts which are authenticated via Visual Studio fail to authenticate with the SharedTokenCacheCredential. This is because Visual Studio authenticates MSA accounts via the MSA passthrough tenant, a tenant legacy applications used to authenticate MSA accounts prior to the "common" tenant being added. However when the SharedTokenCacheCredential attempts to authenticate these accounts it defaults to authenticating them in their home tenant which fails. Unfortunately there is no good way for the SharedTokenCacheCredential to identify this scenario and properly authenticate MSA accounts in this case.

For this reason we have decided to disable the SharedTokenCacheCredential by default in the DefaultAzureCredential so it will authenticate properly via the VisualStudioCredential. This basically makes the workaround I specified above the default behavior. Because this is will be a behavioral breaking change, albeit a very minor one with no impact for most users, we want to preview the change to insure we've had ample time to receive feedback and assess the full impact. We plan to release this change after our 1.3.0 GA release in 1.4.0-beta.2 by mid January. Customers impacted by this issue can still use the workaround described above in the meantime, and can upgrade with or without removing this workaround once the fix is released.

@jtourlamain
Copy link

I have the same issue with the secretclient. The workaround doesn't seem to work. When debugging in Visual Studio 2019.

<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.0.2" />
<PackageReference Include="Azure.Identity" Version="1.3.0" />
<PackageReference Include="Microsoft.Azure.Services.AppAuthentication" Version="1.6.0" />

.NET core 3.1 program.cs

 public static void Main(string[] args)
 {
     CreateHostBuilder(args).Build().Run();
 }

 public static IHostBuilder CreateHostBuilder(string[] args) =>
     Host.CreateDefaultBuilder(args)
      .ConfigureWebHostDefaults(webBuilder =>
      {
          webBuilder.UseStartup<Startup>();
          webBuilder.ConfigureAppConfiguration((ctx, b) =>
          {
              var config = b.Build();
              var secretClient = new SecretClient(new Uri(config["KeyVault:BaseUrl"]), new DefaultAzureCredential(new DefaultAzureCredentialOptions { ExcludeSharedTokenCacheCredential = true }));
              b.AddAzureKeyVault(secretClient, new KeyVaultSecretManager());
          });
            });
}

The error message is starting with {"error":{"code":"Forbidden","message":"Access denied to first party service.\r\nCaller: name=from-infra;tid=f8cdef but the tenantid is not mine.

With the Microsoft.Azure.Services.AppAuthentication lib everything works fine using (while debugging in Visual Studio and when running as an Azure Web app with MI)

var config = b.Build();
var tokenProvider = new AzureServiceTokenProvider();
var kvClient = new KeyVaultClient((authority, resource, scope) => tokenProvider.KeyVaultTokenCallback(authority, resource, scope));
b.AddAzureKeyVault(config["KeyVault:BaseUrl"], kvClient, new DefaultKeyVaultSecretManager());

@christothes
Copy link
Member

@jtourlamain Thanks for providing this example. Just to validate that you are failing with the VisualStudioCredential, could you try your scenario by using the VisualStudioCredential directly, rather than the DefaultAzureCredential?

@christothes christothes added the needs-author-feedback Workflow: More information is needed from author to address the issue. label Feb 17, 2021
@jtourlamain
Copy link

@christothes the VisualStudioCredential doesn't work. I used:

var config = b.Build();
var secretClient = new SecretClient(new Uri(config["KeyVault:BaseUrl"]),  new VisualStudioCredential());
b.AddAzureKeyVault(secretClient, new KeyVaultSecretManager());

Maybe it has something to do with the fact that some of us have multiple accounts and those accounts have access to multiple tenants?

What does work is:

var config = b.Build();
DefaultAzureCredentialOptions options = new DefaultAzureCredentialOptions() { ExcludeSharedTokenCacheCredential = true, VisualStudioTenantId = config["tenantid"] };
var secretClient = new SecretClient(new Uri(config["KeyVault:BaseUrl"]), new DefaultAzureCredential(options));
b.AddAzureKeyVault(secretClient, new KeyVaultSecretManager());

@christothes
Copy link
Member

@jtourlamain Thanks for providing these details. Does your scenario require only the one tenantId? If so you can also set the preferred tenant by setting the AZURE_TENANT_ID environment variable. This is equivalent to setting the VisualStudioTenantId

public string VisualStudioCodeTenantId { get; set; } = GetNonEmptyStringOrNull(EnvironmentVariables.TenantId);

public static string TenantId => Environment.GetEnvironmentVariable("AZURE_TENANT_ID");

In addition, you may want to update to the latest version of the Azure.Identity package.

@ghost ghost added the no-recent-activity There has been no recent activity on this issue. label Feb 25, 2021
@ghost
Copy link

ghost commented Feb 25, 2021

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!

@jsquire jsquire modified the milestones: [2021] March, [2021] April Mar 8, 2021
@ghost ghost removed the no-recent-activity There has been no recent activity on this issue. label Mar 8, 2021
@ghost ghost added the no-recent-activity There has been no recent activity on this issue. label Mar 15, 2021
@ghost
Copy link

ghost commented Mar 15, 2021

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!

@GPetrites
Copy link

I believe I am having the exact same issue when accessing AppConfiguration.

Here's the steps I've taken:

  1. Created an Azure App Configuration service with one key. Granted myself "App Configuration Data Reader" in addition to "Owner"
  2. Created a brand new ASP.NET Core Web API app. Target framework 5.0
  3. Added packages:
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
    <PackageReference Include="Azure.Identity" Version="1.3.0" />
    <PackageReference Include="Microsoft.Azure.AppConfiguration.AspNetCore" Version="4.2.0" />
  </ItemGroup>

</Project>
  1. Added the following to Program.cs and used my app configuration endpoint as the Uri and the tenant id owning the App Configuration. Note that I tried using both VisualStudioCredential and DefaultAzureCredential.
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureAppConfiguration((hostingContext, config) =>
                    {
                        //var credentials = new VisualStudioCredential(new VisualStudioCredentialOptions { TenantId= "99999999-9999-9999-9999-999999999999" });
                        var credentials = new DefaultAzureCredential();

                        config.AddAzureAppConfiguration(options =>
                        {
                            options.Connect(new Uri("https://xxxxxxxxx.azconfig.io"), credentials);
                        });
                    });

                    webBuilder.UseStartup<Startup>();
                });
  1. Verify that I was logging in as the correct account in Visual Studio and that the account was selected under Azure Service Authentication. This account I am using has access to several different Azure tenants. The tenant id I supplied is the correct tenant id for the App Configuration Service.

Trying the above would throw a 403 FORBIDDEN error both either DefaultAzureCredential and VisualStudioCredential with tenant id provided in code.

Suspecting the multiple tenants for my account to be an issue, I tried another account which has access to only this tenant and I was successful.

I then tried setting the environment variable AZURE_TENANT_ID with the desired tenant and was also successful.

What appears to be broken is:

  • using an account with access to multiple tenants
  • AND trying to specify the tenant id using the VisualStudioCredentialOptions

As I prefer using DefaultAzureCredential as it works both locally and under an App Service, I'm good with the AZURE_TENANT_ID solution, but using VisualStudioCredentialOptions to specify the tenant id should be resolved.

@ghost ghost removed the no-recent-activity There has been no recent activity on this issue. label Mar 25, 2021
@ghost ghost added the no-recent-activity There has been no recent activity on this issue. label Apr 2, 2021
@ghost
Copy link

ghost commented Apr 2, 2021

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!

@scottaddie
Copy link
Member

scottaddie commented Apr 2, 2021

I'm able to reproduce the issue too. My account has access to multiple tenants. I'm using VS 2019 16.9.2 with an ASP.NET Core 5.0 Blazor Server app. Setting the AZURE_TENANT_ID environment variable fixes it. Here are the relevant pieces of the app:

.csproj file

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.0.2" />
    <PackageReference Include="Azure.Identity" Version="1.3.0" />
  </ItemGroup>

</Project>

Program.cs

public class Program
{
    public static Task Main(string[] args) =>
        CreateHostBuilder(args).Build().RunAsync();

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((_, config) =>
            {
                var secretClient = new SecretClient(
                    new(Environment.GetEnvironmentVariable("VaultUri")),
                    new DefaultAzureCredential());

                config.AddAzureKeyVault(secretClient, new KeyVaultSecretManager());
            })
            .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>());
}

@ghost ghost removed the no-recent-activity There has been no recent activity on this issue. label Apr 2, 2021
@christothes christothes removed the needs-author-feedback Workflow: More information is needed from author to address the issue. label Apr 2, 2021
@jsquire jsquire modified the milestones: [2021] April, [2021] May Apr 6, 2021
@christothes
Copy link
Member

Would you mind providing the logging output after reproducing this with logging enabled? If you use the latest pre-release version of the client, it will produce additional logging from the underlying MSAL library as well.

@christothes christothes added the needs-author-feedback Workflow: More information is needed from author to address the issue. label Apr 7, 2021
@scottaddie
Copy link
Member

@christothes I emailed you the logging output.

@christothes
Copy link
Member

@scottaddie - Thanks for collecting these logs. This is, unfortunately, a know issue. I've linked to a comment from an issue where I looked into this. The short answer is that there is no way to avoid providing the tenant ID hint in these cases.

#19511 (comment)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Azure.Identity bug This issue requires a change to an existing behavior in the product in order to be resolved. Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. needs-author-feedback Workflow: More information is needed from author to address the issue.
Projects
None yet
Development

No branches or pull requests

9 participants