Skip to content

Commit fbc0e05

Browse files
committed
get_msal_token
1 parent fe77743 commit fbc0e05

File tree

4 files changed

+41
-25
lines changed

4 files changed

+41
-25
lines changed

src/azure-cli-core/azure/cli/core/_profile.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -299,26 +299,24 @@ def logout_all(self):
299299
identity.logout_all_users()
300300
identity.logout_all_service_principal()
301301

302-
def get_login_credentials(self, subscription_id=None, aux_subscriptions=None, aux_tenants=None):
302+
def get_login_credentials(self, subscription_id=None, aux_subscriptions=None, aux_tenants=None,
303+
sdk_credential=True):
303304
"""Get a credential compatible with Track 2 SDK."""
304305
if aux_tenants and aux_subscriptions:
305306
raise CLIError("Please specify only one of aux_subscriptions and aux_tenants, not both")
306307

307308
account = self.get_subscription(subscription_id)
308309

309310
managed_identity_type, managed_identity_id = Profile._parse_managed_identity_account(account)
310-
311+
external_credentials = None
311312
if in_cloud_console() and account[_USER_ENTITY].get(_CLOUD_SHELL_ID):
312313
# Cloud Shell
313314
from .auth.msal_credentials import CloudShellCredential
314-
# The credential must be wrapped by CredentialAdaptor so that it can work with SDK.
315-
sdk_cred = CredentialAdaptor(CloudShellCredential())
315+
cred = CloudShellCredential()
316316

317317
elif managed_identity_type:
318318
# managed identity
319-
# The credential must be wrapped by CredentialAdaptor so that it can work with SDK.
320319
cred = ManagedIdentityAuth.credential_factory(managed_identity_type, managed_identity_id)
321-
sdk_cred = CredentialAdaptor(cred)
322320

323321
else:
324322
# user and service principal
@@ -332,13 +330,15 @@ def get_login_credentials(self, subscription_id=None, aux_subscriptions=None, au
332330
if sub[_TENANT_ID] != account[_TENANT_ID]:
333331
external_tenants.append(sub[_TENANT_ID])
334332

335-
credential = self._create_credential(account)
333+
cred = self._create_credential(account)
336334
external_credentials = []
337335
for external_tenant in external_tenants:
338336
external_credentials.append(self._create_credential(account, tenant_id=external_tenant))
339-
sdk_cred = CredentialAdaptor(credential, auxiliary_credentials=external_credentials)
340337

341-
return (sdk_cred,
338+
# Wrapping the credential with CredentialAdaptor makes it compatible with SDK.
339+
cred_result = CredentialAdaptor(cred, auxiliary_credentials=external_credentials) if sdk_credential else cred
340+
341+
return (cred_result,
342342
str(account[_SUBSCRIPTION_ID]),
343343
str(account[_TENANT_ID]))
344344

@@ -404,8 +404,9 @@ def get_raw_token(self, resource=None, scopes=None, subscription=None, tenant=No
404404
def get_msal_token(self, scopes, data):
405405
"""Get VM SSH certificate. Do not use it for other purposes. To get an access token, use get_raw_token instead.
406406
"""
407-
credential, _, _ = self.get_login_credentials()
408-
certificate_string = credential.get_token(*scopes, data=data).token
407+
credential, _, _ = self.get_login_credentials(sdk_credential=False)
408+
from .auth.constants import ACCESS_TOKEN
409+
certificate_string = credential.acquire_token(scopes, data=data)[ACCESS_TOKEN]
409410
# The first value used to be username, but it is no longer used.
410411
return None, certificate_string
411412

src/azure-cli-core/azure/cli/core/auth/credential_adaptor.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ def _prepare_msal_kwargs(options=None):
5757
# Both get_token's kwargs and get_token_info's options are accepted as their schema is the same (at least for now).
5858
msal_kwargs = {}
5959
if options:
60-
# For VM SSH. 'data' support is a CLI-specific extension.
61-
# SDK doesn't support 'data': https://github.com/Azure/azure-sdk-for-python/pull/16397
62-
if 'data' in options:
63-
msal_kwargs['data'] = options['data']
6460
# For CAE
6561
if 'claims' in options:
6662
msal_kwargs['claims_challenge'] = options['claims']

src/azure-cli-core/azure/cli/core/auth/tests/test_credential_adaptor.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def _now_timestamp_mock():
4444

4545
class TestCredentialAdaptor(unittest.TestCase):
4646

47-
@mock.patch('azure.cli.core.auth.util._now_timestamp', new=_now_timestamp_mock)
47+
@mock.patch('azure.cli.core.auth.util.now_timestamp', new=_now_timestamp_mock)
4848
def test_get_token(self):
4949
msal_cred = MsalCredentialStub()
5050
sdk_cred = CredentialAdaptor(msal_cred)
@@ -56,15 +56,11 @@ def test_get_token(self):
5656
assert access_token.token == MOCK_ACCESS_TOKEN
5757
assert access_token.expires_on == 1630920323
5858

59-
# Note that SDK doesn't support 'data'. This is a CLI-specific extension.
60-
sdk_cred.get_token('https://management.core.windows.net//.default', data=MOCK_DATA)
61-
assert msal_cred.acquire_token_kwargs['data'] == MOCK_DATA
62-
6359
sdk_cred.get_token('https://management.core.windows.net//.default', claims=MOCK_CLAIMS)
6460
assert msal_cred.acquire_token_claims_challenge == MOCK_CLAIMS
6561

6662

67-
@mock.patch('azure.cli.core.auth.util._now_timestamp', new=_now_timestamp_mock)
63+
@mock.patch('azure.cli.core.auth.util.now_timestamp', new=_now_timestamp_mock)
6864
def test_get_token_info(self):
6965
msal_cred = MsalCredentialStub()
7066
sdk_cred = CredentialAdaptor(msal_cred)
@@ -78,10 +74,6 @@ def test_get_token_info(self):
7874

7975
assert msal_cred.acquire_token_scopes == ['https://management.core.windows.net//.default']
8076

81-
# Note that SDK doesn't support 'data'. If 'data' were supported, it should be tested with:
82-
sdk_cred.get_token_info('https://management.core.windows.net//.default', options={'data': MOCK_DATA})
83-
assert msal_cred.acquire_token_kwargs['data'] == MOCK_DATA
84-
8577
sdk_cred.get_token_info('https://management.core.windows.net//.default', options={'claims': MOCK_CLAIMS})
8678
assert msal_cred.acquire_token_claims_challenge == MOCK_CLAIMS
8779

src/azure-cli-core/azure/cli/core/tests/test_profile.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ def __init__(self, *args, **kwargs):
5050
# If acquire_token_scopes is checked, make sure to create a new instance of MsalCredentialStub
5151
# to avoid interference from other tests.
5252
self.acquire_token_scopes = None
53+
self.acquire_token_data=None
5354
super().__init__()
5455

5556
def acquire_token(self, scopes, **kwargs):
5657
self.acquire_token_scopes = scopes
58+
self.acquire_token_data = kwargs.get('data')
5759
return {
5860
'access_token': MOCK_ACCESS_TOKEN,
5961
'token_type': 'Bearer',
@@ -1287,6 +1289,31 @@ def cloud_shell_credential_factory():
12871289
with self.assertRaisesRegex(CLIError, 'Cloud Shell'):
12881290
profile.get_raw_token(resource='http://test_resource', tenant=self.tenant_id)
12891291

1292+
@mock.patch('azure.cli.core.auth.identity.Identity.get_user_credential')
1293+
def test_get_msal_token(self, get_user_credential_mock):
1294+
credential_mock_temp = MsalCredentialStub()
1295+
get_user_credential_mock.return_value = credential_mock_temp
1296+
cli = DummyCli()
1297+
1298+
storage_mock = {'subscriptions': None}
1299+
profile = Profile(cli_ctx=cli, storage=storage_mock)
1300+
consolidated = profile._normalize_properties(self.user1,
1301+
[self.subscription1],
1302+
False, None, None)
1303+
profile._set_subscriptions(consolidated)
1304+
1305+
MOCK_DATA = {
1306+
'key_id': 'test',
1307+
'req_cnf': 'test',
1308+
'token_type': 'ssh-cert'
1309+
}
1310+
result = profile.get_msal_token(['https://pas.windows.net/CheckMyAccess/Linux/.default'],
1311+
MOCK_DATA)
1312+
1313+
assert result == (None, MOCK_ACCESS_TOKEN)
1314+
assert credential_mock_temp.acquire_token_scopes == ['https://pas.windows.net/CheckMyAccess/Linux/.default']
1315+
assert credential_mock_temp.acquire_token_data == MOCK_DATA
1316+
12901317
@mock.patch('azure.cli.core.auth.identity.Identity.logout_service_principal')
12911318
@mock.patch('azure.cli.core.auth.identity.Identity.logout_user')
12921319
def test_logout(self, logout_user_mock, logout_service_principal_mock):

0 commit comments

Comments
 (0)