зеркало из https://github.com/Azure/azure-cli.git
rest-scope
This commit is contained in:
Родитель
1d062eebac
Коммит
9292267c86
|
@ -867,11 +867,16 @@ def check_connectivity(url='https://azure.microsoft.com', max_retries=5, timeout
|
|||
|
||||
|
||||
def send_raw_request(cli_ctx, method, url, headers=None, uri_parameters=None, # pylint: disable=too-many-locals,too-many-branches,too-many-statements
|
||||
body=None, skip_authorization_header=False, resource=None, output_file=None,
|
||||
body=None, skip_authorization_header=False, resource=None, scopes=None, output_file=None,
|
||||
generated_client_request_id_name='x-ms-client-request-id'):
|
||||
import uuid
|
||||
from requests import Session, Request
|
||||
from requests.structures import CaseInsensitiveDict
|
||||
from .auth.util import resource_to_scopes
|
||||
|
||||
# Prefer MSAL-styled scopes over ADAL-styled resource
|
||||
if resource and not scopes:
|
||||
scopes = resource_to_scopes(resource)
|
||||
|
||||
result = CaseInsensitiveDict()
|
||||
for s in headers or []:
|
||||
|
@ -952,13 +957,13 @@ def send_raw_request(cli_ctx, method, url, headers=None, uri_parameters=None, #
|
|||
|
||||
# Prepare the Bearer token for `Authorization` header
|
||||
if not skip_authorization_header and url.lower().startswith('https://'):
|
||||
# Prepare `resource` for `get_raw_token`
|
||||
if not resource:
|
||||
# Prepare `scopes` for `get_raw_token`
|
||||
if not scopes:
|
||||
# If url starts with ARM endpoint, like `https://management.azure.com/`,
|
||||
# use `active_directory_resource_id` for resource, like `https://management.core.windows.net/`.
|
||||
# use `active_directory_resource_id` for scopes, like `https://management.core.windows.net//.default`.
|
||||
# This follows the same behavior as `azure.cli.core.commands.client_factory._get_mgmt_service_client`
|
||||
if url.lower().startswith(endpoints.resource_manager.rstrip('/')):
|
||||
resource = endpoints.active_directory_resource_id
|
||||
scopes = resource_to_scopes(endpoints.active_directory_resource_id)
|
||||
else:
|
||||
from azure.cli.core.cloud import CloudEndpointNotSetException
|
||||
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, #
|
|||
except CloudEndpointNotSetException:
|
||||
continue
|
||||
if isinstance(value, str) and url.lower().startswith(value.lower()):
|
||||
resource = value
|
||||
scopes = resource_to_scopes(value)
|
||||
break
|
||||
if resource:
|
||||
if scopes:
|
||||
# Prepare `subscription` for `get_raw_token`
|
||||
# If this is an ARM request, try to extract subscription ID from the URL.
|
||||
# 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, #
|
|||
if url.lower().startswith(endpoints.resource_manager.rstrip('/')):
|
||||
token_subscription = _extract_subscription_id(url)
|
||||
if token_subscription:
|
||||
logger.debug('Retrieving token for resource %s, subscription %s', resource, token_subscription)
|
||||
token_info, _, _ = profile.get_raw_token(resource, subscription=token_subscription)
|
||||
logger.debug('Retrieving token for scopes %s, subscription %s', scopes, token_subscription)
|
||||
token_info, _, _ = profile.get_raw_token(scopes=scopes, subscription=token_subscription)
|
||||
else:
|
||||
logger.debug('Retrieving token for resource %s', resource)
|
||||
token_info, _, _ = profile.get_raw_token(resource)
|
||||
logger.debug('Retrieving token for scopes %s', scopes)
|
||||
token_info, _, _ = profile.get_raw_token(scopes=scopes)
|
||||
token_type, token, _ = token_info
|
||||
headers = headers or {}
|
||||
headers['Authorization'] = '{} {}'.format(token_type, token)
|
||||
else:
|
||||
logger.warning("Can't derive appropriate Azure AD resource from --url to acquire an access token. "
|
||||
"If access token is required, use --resource to specify the resource")
|
||||
logger.warning("Can't derive appropriate Microsoft Entra ID scopes from --url to acquire an access token. "
|
||||
"If access token is required, use --scope to specify the scopes")
|
||||
|
||||
# https://requests.readthedocs.io/en/latest/user/advanced/#prepared-requests
|
||||
s = Session()
|
||||
|
|
|
@ -33,11 +33,10 @@ class GraphClient:
|
|||
|
||||
def __init__(self, cli_ctx):
|
||||
self._cli_ctx = cli_ctx
|
||||
self._scopes = resource_to_scopes(cli_ctx.cloud.endpoints.microsoft_graph_resource_id)
|
||||
|
||||
# https://graph.microsoft.com/ (AzureCloud)
|
||||
# https://microsoftgraph.chinacloudapi.cn (AzureChinaCloud)
|
||||
self._resource = cli_ctx.cloud.endpoints.microsoft_graph_resource_id
|
||||
# https://graph.microsoft.com//.default (AzureCloud)
|
||||
# https://microsoftgraph.chinacloudapi.cn/.default (AzureChinaCloud)
|
||||
self._scopes = resource_to_scopes(cli_ctx.cloud.endpoints.microsoft_graph_resource_id)
|
||||
|
||||
# https://graph.microsoft.com
|
||||
# https://microsoftgraph.chinacloudapi.cn
|
||||
|
@ -54,7 +53,7 @@ class GraphClient:
|
|||
|
||||
while True:
|
||||
try:
|
||||
r = send_raw_request(self._cli_ctx, method, url, resource=self._resource, uri_parameters=param,
|
||||
r = send_raw_request(self._cli_ctx, method, url, scopes=self._scopes, uri_parameters=param,
|
||||
body=body)
|
||||
except HTTPError as ex:
|
||||
raise GraphError(ex.response.json()['error']['message'], ex.response) from ex
|
||||
|
|
|
@ -30,7 +30,10 @@ def load_arguments(self, _):
|
|||
'see https://github.com/Azure/azure-cli/blob/dev/doc/use_cli_effectively.md#quoting-issues')
|
||||
c.argument('output_file', help='save response payload to a file')
|
||||
c.argument('resource',
|
||||
help='Resource url for which CLI should acquire a token from AAD in order to access '
|
||||
help='Resource url for which CLI should acquire a token from Microsoft Entra ID in order to access '
|
||||
'the service. Using --scope is preferred.')
|
||||
c.argument('scopes', options_list=['--scope'], nargs='+',
|
||||
help='Scopes for which CLI should acquire a token from Microsoft Entra ID in order to access '
|
||||
'the service. The token will be placed in the Authorization header. By default, '
|
||||
'CLI can figure this out based on --url argument, unless you use ones not in the list '
|
||||
'of "az cloud show --query endpoints"')
|
||||
|
|
|
@ -15,14 +15,15 @@ SECRET_STORE_DEMO = "secret_store_demo"
|
|||
|
||||
|
||||
def rest_call(cmd, url, method=None, headers=None, uri_parameters=None,
|
||||
body=None, skip_authorization_header=False, resource=None, output_file=None):
|
||||
body=None, skip_authorization_header=False, resource=None, scopes=None, output_file=None):
|
||||
from azure.cli.core.commands.transform import unregister_global_transforms
|
||||
# No transform should be performed on `az rest`.
|
||||
unregister_global_transforms(cmd.cli_ctx)
|
||||
|
||||
from azure.cli.core.util import send_raw_request
|
||||
r = send_raw_request(cmd.cli_ctx, method, url, headers, uri_parameters, body,
|
||||
skip_authorization_header, resource, output_file)
|
||||
r = send_raw_request(cmd.cli_ctx, method, url, headers=headers, uri_parameters=uri_parameters, body=body,
|
||||
skip_authorization_header=skip_authorization_header, resource=resource, scopes=scopes,
|
||||
output_file=output_file)
|
||||
if not output_file and r.content:
|
||||
try:
|
||||
return r.json()
|
||||
|
|
Загрузка…
Ссылка в новой задаче