Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ def acquire_token(self, scopes, claims_challenge=None, **kwargs):
from azure.cli.core.azclierror import AuthenticationError
try:
# Check if an access token is returned.
check_result(result, scopes=scopes, claims_challenge=claims_challenge)
check_result(result, tenant=self._msal_app.authority.tenant, scopes=scopes,
claims_challenge=claims_challenge)
except AuthenticationError as ex:
# For VM SSH ('data' is passed), if getting access token fails because
# Conditional Access MFA step-up or compliance check is required, re-launch
Expand Down
15 changes: 13 additions & 2 deletions src/azure-cli-core/azure/cli/core/auth/tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,20 @@ def test_generate_login_command(self):
# No parameter is given
assert _generate_login_command() == 'az login'

# scopes
# tenant
actual = _generate_login_command(tenant='21987a97-4e85-47c5-9a13-9dc3e11b2a9a')
assert actual == 'az login --tenant "21987a97-4e85-47c5-9a13-9dc3e11b2a9a"'

# scope
actual = _generate_login_command(scopes=["https://management.core.windows.net//.default"])
assert actual == 'az login --scope https://management.core.windows.net//.default'
assert actual == 'az login --scope "https://management.core.windows.net//.default"'

# tenant and scopes
actual = _generate_login_command(tenant='21987a97-4e85-47c5-9a13-9dc3e11b2a9a',
scopes=["https://management.core.windows.net//.default"])
assert actual == ('az login --tenant "21987a97-4e85-47c5-9a13-9dc3e11b2a9a" '
'--scope "https://management.core.windows.net//.default"')



if __name__ == '__main__':
Expand Down
15 changes: 12 additions & 3 deletions src/azure-cli-core/azure/cli/core/auth/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,21 @@ def aad_error_handler(error, **kwargs):
raise AuthenticationError(error_description, msal_error=error, recommendation=recommendation)


def _generate_login_command(scopes=None, claims_challenge=None):
def _generate_login_command(tenant=None, scopes=None, claims_challenge=None):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we append the tenant info in re-login recommendation msg only for some error code (for example AADSTS50076)?

Now it seems all failure cases will append this except for 7000215

# Build recommendation message
if error_codes and 7000215 in error_codes:
recommendation = PASSWORD_CERTIFICATE_WARNING
else:
login_command = _generate_login_command(**kwargs)

Copy link
Member Author

@jiasli jiasli Jul 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are many possible AADSTS errors. We cannot enumerate all of them. For example, if you haven't configured MFA in a tenant, acquire_token_silent will fail with

AADSTS50079: Due to a configuration change made by your administrator, or because you moved to a new location, you must enroll in multi-factor authentication to access '797f4846-ba00-4fd7-ba43-dac1f8f63013'.

If you have configured MFA in a tenant but didn't perform MFA in the browser before, acquire_token_silent will fail with

AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access '797f4846-ba00-4fd7-ba43-dac1f8f63013'.

It is a good practice to always specify --tenant so that Azure CLI can only access resources in the specified tenant and also trigger MFA as required by that tenant.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern is whether there will be any cases that adding tenant id during login is misleading? If no such case, then I'm good with this

Copy link
Member Author

@jiasli jiasli Jul 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot think of a case where adding tenant ID is misleading.

--tenant will not be shown for managed identity and Cloud Shell:

check_result(result, scopes=scopes)

login_command = ['az login']

# Rejected by Conditional Access policy, like MFA
# Rejected by Conditional Access policy, like MFA.
# MFA status is not shared between tenants. Specifying tenant triggers the MFA process for that tenant.
# Double quotes are not necessary, but we add them following the best practice to avoid shell interpretation.
if tenant:
login_command.extend(['--tenant', f'"{tenant}"'])

# Some scopes (such as Graph) may require MFA while ARM may not.
# Specifying scope triggers the MFA process for that scope.
if scopes:
login_command.append('--scope {}'.format(' '.join(scopes)))
login_command.append('--scope')
for s in scopes:
login_command.append(f'"{s}"')

# Rejected by CAE
if claims_challenge:
Expand Down
Loading