Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion src/azure-cli-core/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Release History
===============

2.17.11
2.18.10
+++++++

* Migrate the authentication library from ADAL to MSAL.
Expand Down
28 changes: 16 additions & 12 deletions src/azure-cli-core/azure/cli/core/_identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,15 @@ def login_with_service_principal_secret(self, client_id, client_secret):
if self._cred_cache:
self._cred_cache.save_service_principal_cred(entry)

credential = ClientSecretCredential(self.tenant_id, client_id, client_secret, authority=self.authority)
credential = ClientSecretCredential(self.tenant_id, client_id, client_secret, authority=self.authority,
**self._credential_kwargs)
return credential

def login_with_service_principal_certificate(self, client_id, certificate_path):
# Use CertificateCredential
# TODO: support use_cert_sn_issuer in CertificateCredential
credential = CertificateCredential(self.tenant_id, client_id, certificate_path, authority=self.authority)
credential = CertificateCredential(self.tenant_id, client_id, certificate_path, authority=self.authority,
**self._credential_kwargs)

# CertificateCredential.__init__ will verify the certificate
# Persist to encrypted cache
Expand Down Expand Up @@ -207,14 +209,16 @@ def login_with_managed_identity(self, scopes, identity_id=None): # pylint: disa
if identity_id:
# Try resource ID
if is_valid_resource_id(identity_id):
credential = ManagedIdentityCredential(identity_config={"mi_res_id": identity_id})
credential = ManagedIdentityCredential(identity_config={"mi_res_id": identity_id},
**self._credential_kwargs)
token = credential.get_token(*scopes)
id_type = self.MANAGED_IDENTITY_RESOURCE_ID
else:
authenticated = False
try:
# Try client ID
credential = ManagedIdentityCredential(client_id=identity_id)
credential = ManagedIdentityCredential(client_id=identity_id,
**self._credential_kwargs)
token = credential.get_token(*scopes)
id_type = self.MANAGED_IDENTITY_CLIENT_ID
authenticated = True
Expand All @@ -230,7 +234,8 @@ def login_with_managed_identity(self, scopes, identity_id=None): # pylint: disa
if not authenticated:
try:
# Try object ID
credential = ManagedIdentityCredential(identity_config={"object_id": identity_id})
credential = ManagedIdentityCredential(identity_config={"object_id": identity_id},
**self._credential_kwargs)
token = credential.get_token(*scopes)
id_type = self.MANAGED_IDENTITY_OBJECT_ID
authenticated = True
Expand All @@ -248,7 +253,7 @@ def login_with_managed_identity(self, scopes, identity_id=None): # pylint: disa

else:
# Use the default managed identity. It can be either system assigned or user assigned.
credential = ManagedIdentityCredential()
credential = ManagedIdentityCredential(**self._credential_kwargs)
token = credential.get_token(*scopes)

decoded = _decode_access_token(token)
Expand All @@ -274,7 +279,7 @@ def login_with_managed_identity(self, scopes, identity_id=None): # pylint: disa
return credential, managed_identity_info

def login_in_cloud_shell(self, scopes):
credential = ManagedIdentityCredential()
credential = ManagedIdentityCredential(**self._credential_kwargs)
# As Managed Identity doesn't have ID token, we need to get an initial access token and extract info from it
# The scopes is only used for acquiring the initial access token
token = credential.get_token(*scopes)
Expand Down Expand Up @@ -345,9 +350,9 @@ def get_service_principal_credential(self, client_id, use_cert_sn_issuer):
self._msal_secret_store.retrieve_secret_of_service_principal(client_id, self.tenant_id)
# TODO: support use_cert_sn_issuer in CertificateCredential
if client_secret:
return ClientSecretCredential(self.tenant_id, client_id, client_secret)
return ClientSecretCredential(self.tenant_id, client_id, client_secret, **self._credential_kwargs)
if certificate_path:
return CertificateCredential(self.tenant_id, client_id, certificate_path)
return CertificateCredential(self.tenant_id, client_id, certificate_path, **self._credential_kwargs)
raise CLIError("Secret of service principle {} not found. Please run 'az login'".format(client_id))

def get_environment_credential(self):
Expand All @@ -361,9 +366,8 @@ def get_environment_credential(self):

return EnvironmentCredential(**self._credential_kwargs)

@staticmethod
def get_managed_identity_credential(client_id=None):
return ManagedIdentityCredential(client_id=client_id)
def get_managed_identity_credential(self, client_id=None):
return ManagedIdentityCredential(client_id=client_id, **self._credential_kwargs)

def migrate_tokens(self):
"""Migrate ADAL token cache to MSAL."""
Expand Down
4 changes: 2 additions & 2 deletions src/azure-cli-core/azure/cli/core/_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ def _create_identity_credential(self, account, aux_tenant_id=None, client_id=Non
if in_cloud_console() and account[_USER_ENTITY].get(_CLOUD_SHELL_ID):
if aux_tenant_id:
raise CLIError("Tenant shouldn't be specified for Cloud Shell account")
return Identity.get_managed_identity_credential()
return identity.get_managed_identity_credential()

# EnvironmentCredential. Ignore user_type
if is_environment:
Expand All @@ -680,7 +680,7 @@ def _create_identity_credential(self, account, aux_tenant_id=None, client_id=Non
# MSI
if aux_tenant_id:
raise CLIError("Tenant shouldn't be specified for MSI account")
return Identity.get_managed_identity_credential(identity_id)
return identity.get_managed_identity_credential(identity_id)

def get_login_credentials(self, resource=None, client_id=None, subscription_id=None, aux_subscriptions=None,
aux_tenants=None):
Expand Down
4 changes: 3 additions & 1 deletion src/azure-cli/azure/cli/command_modules/profile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,11 @@ def load_arguments(self, command):
c.argument('username', options_list=['--username', '-u'], help='user name, service principal, or managed service identity ID')
c.argument('tenant', options_list=['--tenant', '-t'], help='The AAD tenant, must provide when using service principals.', validator=validate_tenant)
c.argument('tenant_access', action='store_true',
deprecate_info=c.deprecate(target='--tenant-access', hide=True),
help='Only log in to the home tenant or the tenant specified by --tenant. CLI will not perform '
'ARM operations to list tenants and subscriptions. Then you may run tenant-level commands, '
'such as `az ad`, `az account get-access-token`.')
c.argument('allow_no_subscriptions', action='store_true', deprecate_info=c.deprecate(target='--allow-no-subscriptions', expiration='3.0.0', redirect="--tenant-access", hide=False),
c.argument('allow_no_subscriptions', action='store_true',
help="Support access tenants without subscriptions. It's uncommon but useful to run tenant level commands, such as `az ad`")
c.ignore('_subscription') # hide the global subscription parameter
c.argument('identity', options_list=('-i', '--identity'), action='store_true', help="Log in using the Virtual Machine's managed identity", arg_group='Managed Identity')
Expand All @@ -72,6 +73,7 @@ def load_arguments(self, command):
help="Use CLI's old authentication flow based on device code. CLI will also use this if it can't launch a browser in your behalf, e.g. in remote SSH or Cloud Shell")
c.argument('use_cert_sn_issuer', action='store_true', help='used with a service principal configured with Subject Name and Issuer Authentication in order to support automatic certificate rolls')
c.argument('environment', options_list=['--environment', '-e'], action='store_true',
deprecate_info=c.deprecate(target='--environment', hide=True),
help='Use EnvironmentCredential. Both user and service principal accounts are supported. '
'For required environment variables, see https://docs.microsoft.com/en-us/python/api/overview/azure/identity-readme?view=azure-python#environment-variables')

Expand Down
18 changes: 0 additions & 18 deletions src/azure-cli/azure/cli/command_modules/profile/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,6 @@
text: az login --identity
- name: Log in using a VM's user-assigned managed identity. Client or object ids of the service identity also work.
text: az login --identity -u /subscriptions/<subscriptionId>/resourcegroups/myRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID
- name: Log in with a service principal using EnvironmentCredential.
text: |-
# Bash script
export AZURE_TENANT_ID='<tenant ID>'
export AZURE_CLIENT_ID='<service principal appId>'
# With secret
export AZURE_CLIENT_SECRET='<secret>'
# Or with certificate
# export AZURE_CLIENT_CERTIFICATE_PATH='<path to a PEM-encoded certificate file>'
az login --environment
- name: Log in with a user account using EnvironmentCredential.
text: |-
# Bash script
# AZURE_CLIENT_ID defaults to Azure CLI's client ID
# export AZURE_CLIENT_ID='04b07795-8ddb-461a-bbee-02f9e1bf7b46'
export AZURE_USERNAME='<username>'
export AZURE_PASSWORD='<password>'
az login --environment
"""

helps['account'] = """
Expand Down