Description
Library name and version
Azure.Identity 1.13.2
Describe the bug
Hey team.
The AzureCliCredential
authentication differs from ManagedIdentity authentication. This only works when deployed to Azure using Managed Identity, obviously not locally, because we're using ManagedIdentityCredential
.
var credential = new ChainedTokenCredential(
new ManagedIdentityCredential());
string[] scopes = ["https://graph.microsoft.com/.default", "Mail.Read"];
graphServiceClient = new GraphServiceClient(credential, scopes);
var result = await graphServiceClient.Users[userId]
.Messages[emailId]
.GetAsync();
Snipped simplified
But now the problem is that below code should work locally, but does not work. Azure CLI does not seem to know how to use multiple scopes.
var credential = new ChainedTokenCredential(
new AzureCliCredential());
string[] scopes = ["https://graph.microsoft.com/.default", "Mail.Read"];
graphServiceClient = new GraphServiceClient(credential, scopes);
var result = await graphServiceClient.Users[userId]
.Messages[emailId]
.GetAsync();
Snipped simplified
The exception is:
Exception: Azure.Identity.AuthenticationFailedException: The ChainedTokenCredential failed due to an unhandled exception: AzureCliCredential authentication failed: To convert to a resource string the specified array must be exactly length 1 (Parameter 'scopes')
---> Azure.Identity.AuthenticationFailedException: AzureCliCredential authentication failed: To convert to a resource string the specified array must be exactly length 1 (Parameter 'scopes')
---> System.ArgumentException: To convert to a resource string the specified array must be exactly length 1 (Parameter 'scopes')
at Azure.Identity.ScopeUtilities.ScopesToResource(String[] scopes)
at Azure.Identity.AzureCliCredential.RequestCliAccessTokenAsync(Boolean async, TokenRequestContext context, CancellationToken cancellationToken)
at Azure.Identity.AzureCliCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)
This implementation difference leads to this code working on Azure, but not locally. It may be very big blocker, if this would prevent developers from using Managed Identity, because it's breaking local development.
Expected behavior
The AzureCliCredential
should support multiple scopes and behave at least closely to how ManagedIdentity
works.
Possible use cases that need this are for example (as shown in the snippets) accessing MS Graph using explicit scopes.
Actual behavior
AzureCliCredential
throws an exception.
Exception: Azure.Identity.AuthenticationFailedException: The ChainedTokenCredential failed due to an unhandled exception: AzureCliCredential authentication failed: To convert to a resource string the specified array must be exactly length 1 (Parameter 'scopes')
---> Azure.Identity.AuthenticationFailedException: AzureCliCredential authentication failed: To convert to a resource string the specified array must be exactly length 1 (Parameter 'scopes')
---> System.ArgumentException: To convert to a resource string the specified array must be exactly length 1 (Parameter 'scopes')
at Azure.Identity.ScopeUtilities.ScopesToResource(String[] scopes)
at Azure.Identity.AzureCliCredential.RequestCliAccessTokenAsync(Boolean async, TokenRequestContext context, CancellationToken cancellationToken)
at Azure.Identity.AzureCliCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)
Reproduction Steps
var credential = new ChainedTokenCredential(
new AzureCliCredential());
string[] scopes = ["https://graph.microsoft.com/.default", "Mail.Read"];
graphServiceClient = new GraphServiceClient(credential, scopes);
var result = await graphServiceClient.Users[userId]
.Messages[emailId]
.GetAsync();
Environment
.NET SDK:
Version: 9.0.102
Commit: cb83cd4923
Workload version: 9.0.100-manifests.43af17c7
MSBuild version: 17.12.18+ed8c6aec5
Metadata
Metadata
Assignees
Labels
Type
Projects
Status