Skip to content

Track 2 SDK fails to work with MSAL due to invalid credential_scopes #12947

@jiasli

Description

@jiasli

Track 1 SDK - working

Previously in Track 1 SDK, the corresponding name of scopes is resource. The SDK itself doesn't maintain/know the resource. resource is provide by Azure CLI and used in token retrieval.

mgmt-plane - azure/cli/core/commands/client_factory.py:

resource = resource or cli_ctx.cloud.endpoints.active_directory_resource_id

data-plane - azure/cli/command_modules/role/_client_factory.py:

cred, _, tenant_id = profile.get_login_credentials(
    resource=cli_ctx.cloud.endpoints.active_directory_graph_resource_id)

Then the resource is used in get_login_credentials:

def get_login_credentials(self, resource=None, subscription_id=None, aux_subscriptions=None, aux_tenants=None):
    if aux_tenants and aux_subscriptions:

and saved in the closure for _retrieve_token.

Later on, when signed_session is called, it doesn't accept a resource and uses the one passed to get_login_credentials instead.

def signed_session(self, session=None):

Track 2 SDK - not working

In Track 2 SDK, the scopes is managed by the SDK itself:

self.credential_scopes = ['https://management.azure.com/.default']
self.credential_scopes.extend(kwargs.pop('credential_scopes', []))

Then scopes is passed to get_token

self._token = self._credential.get_token(*self._scopes)

If used in a sovereign cloud (like China cloud), the client needs to be created as

StorageManagementClient(credential_scopes=['https://management.core.chinacloudapi.cn/.default'])

Thus, credential_scopes becomes

['https://management.azure.com/.default', 'https://management.core.chinacloudapi.cn/.default']

which is not valid according to OAuth 2.0 authorization code flow, because it contains more than one resource:

Parameter Type Description
scope optional A space-separated list of scopes. The scopes must all be from a single resource, along with OIDC scopes (profile, openid, email).

This can also be verified with

az account get-access-token --scopes https://management.core.chinacloudapi.cn/.default https://management.azure.com/.default --debug

azure.core.pipeline.policies.http_logging_policy : Request URL: 'https://login.microsoftonline.com/54826b22-38d6-4fb2-bad9-b7b93a3e9c5a/oauth2/v2.0/token'
azure.core.pipeline.policies.http_logging_policy : Request method: 'POST'

azure.core.pipeline.policies.http_logging_policy : Response status: 400

msal.application : Refresh failed. invalid_scope: AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope https://management.azure.com/.default https://management.core.chinacloudapi.cn/.default offline_access openid profile is not valid. .default scope can't be combined with resource-specific scopes.

Why this issue doesn't happen now (Track 2 SDK + ADAL)

This is because when get_token from Azure CLI is called, scopes is totally unused/discarded, thus forcing the Track 2 SDK client to use the resource provided by Azure CLI in get_login_credentials.

In the MSAL integration process (Azure/azure-cli#14690), I try to honor the scopes provided by SDK and hit this issue.

Solution

The SDK needs to override the default credential_scopes if credential_scopes is provided in kwargs, so that the default value 'https://management.azure.com/.default' doesn't appear in self.credential_scopes.

A fix can be like this:

self.credential_scopes = kwargs.pop('credential_scopes', ['https://management.azure.com/.default'])

whose value is

['https://management.core.chinacloudapi.cn/.default']

Metadata

Metadata

Labels

Autorest IssueAzure.CoreClientThis issue points to a problem in the data-plane of the library.bugThis issue requires a change to an existing behavior in the product in order to be resolved.needs-team-attentionWorkflow: This issue needs attention from Azure service team or SDK team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions