Skip to content

Commit deb3c5f

Browse files
committed
rest-scope
1 parent 1d062ee commit deb3c5f

File tree

5 files changed

+30
-22
lines changed

5 files changed

+30
-22
lines changed

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

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -867,11 +867,16 @@ def check_connectivity(url='https://azure.microsoft.com', max_retries=5, timeout
867867

868868

869869
def send_raw_request(cli_ctx, method, url, headers=None, uri_parameters=None, # pylint: disable=too-many-locals,too-many-branches,too-many-statements
870-
body=None, skip_authorization_header=False, resource=None, output_file=None,
870+
body=None, skip_authorization_header=False, resource=None, scopes=None, output_file=None,
871871
generated_client_request_id_name='x-ms-client-request-id'):
872872
import uuid
873873
from requests import Session, Request
874874
from requests.structures import CaseInsensitiveDict
875+
from .auth.util import resource_to_scopes
876+
877+
# Use MSAL-styled scopes instead of ADAL-styled resource
878+
if resource and not scopes:
879+
scopes = resource_to_scopes(resource)
875880

876881
result = CaseInsensitiveDict()
877882
for s in headers or []:
@@ -952,13 +957,13 @@ def send_raw_request(cli_ctx, method, url, headers=None, uri_parameters=None, #
952957

953958
# Prepare the Bearer token for `Authorization` header
954959
if not skip_authorization_header and url.lower().startswith('https://'):
955-
# Prepare `resource` for `get_raw_token`
956-
if not resource:
960+
# Prepare `scopes` for `get_raw_token`
961+
if not scopes:
957962
# If url starts with ARM endpoint, like `https://management.azure.com/`,
958-
# use `active_directory_resource_id` for resource, like `https://management.core.windows.net/`.
963+
# use `active_directory_resource_id` for scopes, like `https://management.core.windows.net//.default`.
959964
# This follows the same behavior as `azure.cli.core.commands.client_factory._get_mgmt_service_client`
960965
if url.lower().startswith(endpoints.resource_manager.rstrip('/')):
961-
resource = endpoints.active_directory_resource_id
966+
scopes = resource_to_scopes(endpoints.active_directory_resource_id)
962967
else:
963968
from azure.cli.core.cloud import CloudEndpointNotSetException
964969
for p in [x for x in dir(endpoints) if not x.startswith('_')]:
@@ -967,9 +972,9 @@ def send_raw_request(cli_ctx, method, url, headers=None, uri_parameters=None, #
967972
except CloudEndpointNotSetException:
968973
continue
969974
if isinstance(value, str) and url.lower().startswith(value.lower()):
970-
resource = value
975+
scopes = resource_to_scopes(value)
971976
break
972-
if resource:
977+
if scopes:
973978
# Prepare `subscription` for `get_raw_token`
974979
# If this is an ARM request, try to extract subscription ID from the URL.
975980
# But there are APIs which don't require subscription ID, like /subscriptions, /tenants
@@ -979,17 +984,17 @@ def send_raw_request(cli_ctx, method, url, headers=None, uri_parameters=None, #
979984
if url.lower().startswith(endpoints.resource_manager.rstrip('/')):
980985
token_subscription = _extract_subscription_id(url)
981986
if token_subscription:
982-
logger.debug('Retrieving token for resource %s, subscription %s', resource, token_subscription)
983-
token_info, _, _ = profile.get_raw_token(resource, subscription=token_subscription)
987+
logger.debug('Retrieving token for scopes %s, subscription %s', scopes, token_subscription)
988+
token_info, _, _ = profile.get_raw_token(scopes=scopes, subscription=token_subscription)
984989
else:
985-
logger.debug('Retrieving token for resource %s', resource)
986-
token_info, _, _ = profile.get_raw_token(resource)
990+
logger.debug('Retrieving token for scopes %s', scopes)
991+
token_info, _, _ = profile.get_raw_token(scopes=scopes)
987992
token_type, token, _ = token_info
988993
headers = headers or {}
989994
headers['Authorization'] = '{} {}'.format(token_type, token)
990995
else:
991-
logger.warning("Can't derive appropriate Azure AD resource from --url to acquire an access token. "
992-
"If access token is required, use --resource to specify the resource")
996+
logger.warning("Can't derive appropriate Microsoft Entra ID scopes from --url to acquire an access token. "
997+
"If access token is required, use --scope to specify the scopes")
993998

994999
# https://requests.readthedocs.io/en/latest/user/advanced/#prepared-requests
9951000
s = Session()

src/azure-cli/azure/cli/command_modules/role/_msgrpah/_graph_client.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,10 @@ class GraphClient:
3333

3434
def __init__(self, cli_ctx):
3535
self._cli_ctx = cli_ctx
36-
self._scopes = resource_to_scopes(cli_ctx.cloud.endpoints.microsoft_graph_resource_id)
3736

38-
# https://graph.microsoft.com/ (AzureCloud)
39-
# https://microsoftgraph.chinacloudapi.cn (AzureChinaCloud)
40-
self._resource = cli_ctx.cloud.endpoints.microsoft_graph_resource_id
37+
# https://graph.microsoft.com//.default (AzureCloud)
38+
# https://microsoftgraph.chinacloudapi.cn/.default (AzureChinaCloud)
39+
self._scopes = resource_to_scopes(cli_ctx.cloud.endpoints.microsoft_graph_resource_id)
4140

4241
# https://graph.microsoft.com
4342
# https://microsoftgraph.chinacloudapi.cn
@@ -54,7 +53,7 @@ def _send(self, method, url, param=None, body=None, api_version=V1_0):
5453

5554
while True:
5655
try:
57-
r = send_raw_request(self._cli_ctx, method, url, resource=self._resource, uri_parameters=param,
56+
r = send_raw_request(self._cli_ctx, method, url, scopes=self._scopes, uri_parameters=param,
5857
body=body)
5958
except HTTPError as ex:
6059
raise GraphError(ex.response.json()['error']['message'], ex.response) from ex

src/azure-cli/azure/cli/command_modules/role/_msgrpah/tests/test_grpah_client.py renamed to src/azure-cli/azure/cli/command_modules/role/_msgrpah/tests/test_graph_client.py

File renamed without changes.

src/azure-cli/azure/cli/command_modules/util/_params.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ def load_arguments(self, _):
3030
'see https://github.com/Azure/azure-cli/blob/dev/doc/use_cli_effectively.md#quoting-issues')
3131
c.argument('output_file', help='save response payload to a file')
3232
c.argument('resource',
33-
help='Resource url for which CLI should acquire a token from AAD in order to access '
33+
help='Resource url for which CLI should acquire a token from Microsoft Entra ID in order to access '
34+
'the service. Using --scope is preferred.')
35+
c.argument('scopes', options_list=['--scope'], nargs='+',
36+
help='Scopes for which CLI should acquire a token from Microsoft Entra ID in order to access '
3437
'the service. The token will be placed in the Authorization header. By default, '
3538
'CLI can figure this out based on --url argument, unless you use ones not in the list '
3639
'of "az cloud show --query endpoints"')

src/azure-cli/azure/cli/command_modules/util/custom.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515

1616

1717
def rest_call(cmd, url, method=None, headers=None, uri_parameters=None,
18-
body=None, skip_authorization_header=False, resource=None, output_file=None):
18+
body=None, skip_authorization_header=False, resource=None, scopes=None, output_file=None):
1919
from azure.cli.core.commands.transform import unregister_global_transforms
2020
# No transform should be performed on `az rest`.
2121
unregister_global_transforms(cmd.cli_ctx)
2222

2323
from azure.cli.core.util import send_raw_request
24-
r = send_raw_request(cmd.cli_ctx, method, url, headers, uri_parameters, body,
25-
skip_authorization_header, resource, output_file)
24+
r = send_raw_request(cmd.cli_ctx, method, url, headers=headers, uri_parameters=uri_parameters, body=body,
25+
skip_authorization_header=skip_authorization_header, resource=resource, scopes=scopes,
26+
output_file=output_file)
2627
if not output_file and r.content:
2728
try:
2829
return r.json()

0 commit comments

Comments
 (0)