Skip to content

[Az.Accounts]: ambiguity in clientfactory.CreateArmClient #18634

Open
@VeryEarly

Description

@VeryEarly

Description

To create track1 SDK client, we use method

public virtual TClient CreateArmClient<TClient>(IAzureContext context, string endpoint) where TClient : Microsoft.Rest.ServiceClient<TClient>

the endpoint passed in will be used to

  • as endpoint: construct base uri ( var baseUri = context.Environment.GetEndpointAsUri(endpoint);)
  • as resourceId: retrieve access token (var creds = AzureSession.Instance.AuthenticationFactory.GetServiceClientCredentials(context, endpoint);)

there are two part of authenticate flow:

  1. when login as access token:
    RenewingTokenCredential(new ExternalAccessToken(GetEndpointToken(context.Account, targetEndpoint), () => GetEndpointToken(context.Account, targetEndpoint)));
private string GetEndpointToken(IAzureAccount account, string targetEndpoint)
        {
            string tokenKey = AzureAccount.Property.AccessToken;
            if (string.Equals(targetEndpoint, AzureEnvironment.Endpoint.AzureKeyVaultServiceEndpointResourceId, StringComparison.OrdinalIgnoreCase))
            {
                tokenKey = AzureAccount.Property.KeyVaultAccessToken;
            }
            if (string.Equals(targetEndpoint, AzureEnvironment.ExtendedEndpoint.MicrosoftGraphEndpointResourceId, StringComparison.OrdinalIgnoreCase))
            {
                tokenKey = Constants.MicrosoftGraphAccessToken;
            }
            if (string.Equals(targetEndpoint, AzureEnvironment.Endpoint.Graph, StringComparison.OrdinalIgnoreCase))
            {
                tokenKey = AzureAccount.Property.GraphAccessToken;
            }
            return account.GetProperty(tokenKey);
        }
  1. otherwise
public IAccessToken Authenticate(
            IAzureAccount account,
            IAzureEnvironment environment,
            string tenant,
            SecureString password,
            string promptBehavior,
            Action<string> promptAction,
            IAzureTokenCache tokenCache,
            string resourceId = AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId)

for flow 1, the targetEndpoint is actually irrelevant to the actual access token (in context.account.extendedproperties, key: Microsoft.Azure.Commands.Common.Authentication.Constants.MicrosoftGraphAccessToken, value: msgraph access token)

When create MSGraph client , as the "CreateArmClient" method suggested, we passed in the endpoint "MicrosoftGraphUrl", however this cannot be matched in flow 1 :

if (string.Equals(targetEndpoint, AzureEnvironment.ExtendedEndpoint.MicrosoftGraphEndpointResourceId, StringComparison.OrdinalIgnoreCase))

which returned the ARM accesstoken instead.

I made a work around #18414 to let it match both MSGraph ResourceId and MSGraph endpoint. A better fix would be use ResourceId for both flow 1 and 2, separate endpoint and resourceId in:

var creds = AzureSession.Instance.AuthenticationFactory.GetServiceClientCredentials(context, context.Environment.GetTokenAudience(endpoint));
var baseUri = context.Environment.GetEndpointAsUri(endpoint);

and in flow 1:

RenewingTokenCredential(new ExternalAccessToken(GetEndpointToken(context.Account, ResourceId), () => GetEndpointToken(context.Account, ResourceId)));

Metadata

Metadata

Assignees

No one assigned

    Labels

    AccountsIssues in Az.Accounts except authentication relatedAuthenticationfeature-requestThis issue requires a new behavior in the product in order be resolved.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions