diff --git a/src/azure-cli-core/HISTORY.rst b/src/azure-cli-core/HISTORY.rst index 7f6bb43cb32..c54f52f23e7 100644 --- a/src/azure-cli-core/HISTORY.rst +++ b/src/azure-cli-core/HISTORY.rst @@ -4,6 +4,7 @@ Release History =============== 2.0.52 ++++++ +* core: support cross tenant resource provisioning for multi-tenant service principal * Fix bug where ids piped from a command with tsv output is improperly parsed. 2.0.51 diff --git a/src/azure-cli-core/azure/cli/core/_profile.py b/src/azure-cli-core/azure/cli/core/_profile.py index 8f517992f24..ce639b59549 100644 --- a/src/azure-cli-core/azure/cli/core/_profile.py +++ b/src/azure-cli-core/azure/cli/core/_profile.py @@ -496,7 +496,8 @@ def get_login_credentials(self, resource=None, subscription_id=None, aux_subscri for ext_sub in ext_subs: sub = self.get_subscription(ext_sub) if sub[_TENANT_ID] != account[_TENANT_ID]: - external_tenants_info.append((sub[_USER_ENTITY][_USER_NAME], sub[_TENANT_ID])) + # external_tenants_info.append((sub[_USER_ENTITY][_USER_NAME], sub[_TENANT_ID])) + external_tenants_info.append(sub) if identity_type is None: def _retrieve_token(): @@ -507,12 +508,18 @@ def _retrieve_token(): account[_TENANT_ID], resource) use_cert_sn_issuer = account[_USER_ENTITY].get(_SERVICE_PRINCIPAL_CERT_SN_ISSUER_AUTH) return self._creds_cache.retrieve_token_for_service_principal(username_or_sp_id, resource, + account[_TENANT_ID], use_cert_sn_issuer) def _retrieve_tokens_from_external_tenants(): external_tokens = [] - for u, t in external_tenants_info: - external_tokens.append(self._creds_cache.retrieve_token_for_user(u, t, resource)) + for s in external_tenants_info: + if user_type == _USER: + external_tokens.append(self._creds_cache.retrieve_token_for_user( + username_or_sp_id, s[_TENANT_ID], resource)) + else: + external_tokens.append(self._creds_cache.retrieve_token_for_service_principal( + username_or_sp_id, resource, s[_TENANT_ID], resource)) return external_tokens from azure.cli.core.adal_authentication import AdalAuthentication @@ -562,6 +569,7 @@ def get_raw_token(self, resource=None, subscription=None): account[_TENANT_ID], resource) else: creds = self._creds_cache.retrieve_token_for_service_principal(username_or_sp_id, + account[_TENANT_ID], resource) return (creds, str(account[_SUBSCRIPTION_ID]), @@ -878,9 +886,10 @@ def retrieve_token_for_user(self, username, tenant, resource): self.persist_cached_creds() return (token_entry[_TOKEN_ENTRY_TOKEN_TYPE], token_entry[_ACCESS_TOKEN], token_entry) - def retrieve_token_for_service_principal(self, sp_id, resource, use_cert_sn_issuer=False): + def retrieve_token_for_service_principal(self, sp_id, resource, tenant, use_cert_sn_issuer=False): self.load_adal_token_cache() - matched = [x for x in self._service_principal_creds if sp_id == x[_SERVICE_PRINCIPAL_ID]] + matched = [x for x in self._service_principal_creds if sp_id == x[_SERVICE_PRINCIPAL_ID] and + tenant == tenant[_TENANT_ID]] if not matched: raise CLIError("Please run 'az account set' to select active account.") cred = matched[0] diff --git a/src/azure-cli-core/azure/cli/core/tests/test_profile.py b/src/azure-cli-core/azure/cli/core/tests/test_profile.py index f17d99c4212..61402e7fe53 100644 --- a/src/azure-cli-core/azure/cli/core/tests/test_profile.py +++ b/src/azure-cli-core/azure/cli/core/tests/test_profile.py @@ -1050,7 +1050,7 @@ def just_raise(ex): mock_arm_client.subscriptions.list.return_value = [self.subscription1] finder = SubscriptionFinder(cli, lambda _, _1, _2: mock_auth_context, None, lambda _: mock_arm_client) # action - subs = finder.find_from_user_account(self.user1, 'bar', 'NiceTenant', 'http://someresource') + subs = finder.find_from_user_account(self.user1, 'bar', self.tenant_id, 'http://someresource') # assert self.assertEqual([self.subscription1], subs) @@ -1122,7 +1122,7 @@ def just_raise(ex): mock_arm_client.subscriptions.list.return_value = [self.subscription1] finder = SubscriptionFinder(cli, lambda _, _1, _2: mock_auth_context, None, lambda _: mock_arm_client) # action - subs = finder.find_through_interactive_flow('NiceTenant', 'http://someresource') + subs = finder.find_through_interactive_flow(self.tenant_id, 'http://someresource') # assert self.assertEqual([self.subscription1], subs)