2020 "To pass a service principal certificate, use --certificate instead." )
2121
2222
23- def aad_error_handler (error , ** kwargs ):
23+ def aad_error_handler (error , tenant = None , scopes = None , claims_challenge = None ):
2424 """ Handle the error from AAD server returned by ADAL or MSAL. """
2525
2626 # https://learn.microsoft.com/en-us/azure/active-directory/develop/reference-aadsts-error-codes
@@ -41,11 +41,21 @@ def aad_error_handler(error, **kwargs):
4141 error_codes = error .get ('error_codes' )
4242
4343 # Build recommendation message
44+ recommendation = None
4445 if error_codes and 7000215 in error_codes :
4546 recommendation = PASSWORD_CERTIFICATE_WARNING
4647 else :
47- login_command = _generate_login_command (** kwargs )
48- recommendation = "Interactive authentication is needed. Please run:\n {}" .format (login_command )
48+ login_command = _generate_login_command (tenant = tenant , scopes = scopes , claims_challenge = claims_challenge )
49+ login_message = ('Run the command below to authenticate interactively; '
50+ 'additional arguments may be added as needed:\n '
51+ f'{ login_command } ' )
52+
53+ # During a challenge, the exception will caught by azure-mgmt-core, so we show a warning now
54+ if claims_challenge :
55+ logger .info ('Failed to acquire token silently. Error detail: %s' , error_description )
56+ logger .warning (login_message )
57+ else :
58+ recommendation = login_message
4959
5060 from azure .cli .core .azclierror import AuthenticationError
5161 raise AuthenticationError (error_description , msal_error = error , recommendation = recommendation )
@@ -69,10 +79,14 @@ def _generate_login_command(tenant=None, scopes=None, claims_challenge=None):
6979
7080 # Rejected by CAE
7181 if claims_challenge :
72- # Explicit logout is needed: https://github.com/AzureAD/microsoft-authentication-library-for-python/issues/335
73- return 'az logout\n ' + ' ' .join (login_command )
82+ from azure .cli .core .util import b64encode
83+ # Base64 encode the claims_challenge to avoid shell interpretation
84+ claims_challenge_encoded = b64encode (claims_challenge )
85+ login_command .extend (['--claims-challenge' , f'"{ claims_challenge_encoded } "' ])
7486
75- return ' ' .join (login_command )
87+ # Explicit logout is preferred, making sure MSAL cache is purged:
88+ # https://github.com/AzureAD/microsoft-authentication-library-for-python/issues/335
89+ return 'az logout\n ' + ' ' .join (login_command )
7690
7791
7892def resource_to_scopes (resource ):
@@ -113,7 +127,7 @@ def scopes_to_resource(scopes):
113127 return scope
114128
115129
116- def check_result (result , ** kwargs ):
130+ def check_result (result , tenant = None , scopes = None , claims_challenge = None ):
117131 """Parse the result returned by MSAL:
118132
119133 1. Check if the MSAL result contains a valid access token.
@@ -132,7 +146,7 @@ def check_result(result, **kwargs):
132146 set_msal_telemetry (result ['msal_telemetry' ])
133147
134148 if 'error' in result :
135- aad_error_handler (result , ** kwargs )
149+ aad_error_handler (result , tenant = tenant , scopes = scopes , claims_challenge = claims_challenge )
136150
137151 # For user authentication
138152 if 'id_token_claims' in result :
0 commit comments