-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Core] Drop Track 1 SDK authentication #29631
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -3,69 +3,39 @@ | |||||||||||||||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||||||||||||||||
# -------------------------------------------------------------------------------------------- | ||||||||||||||||
|
||||||||||||||||
import requests | ||||||||||||||||
from knack.log import get_logger | ||||||||||||||||
from knack.util import CLIError | ||||||||||||||||
|
||||||||||||||||
from .util import resource_to_scopes | ||||||||||||||||
|
||||||||||||||||
logger = get_logger(__name__) | ||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||
class CredentialAdaptor: | ||||||||||||||||
def __init__(self, credential, resource=None, auxiliary_credentials=None): | ||||||||||||||||
""" | ||||||||||||||||
Adaptor to both | ||||||||||||||||
- Track 1: msrest.authentication.Authentication, which exposes signed_session | ||||||||||||||||
- Track 2: azure.core.credentials.TokenCredential, which exposes get_token | ||||||||||||||||
def __init__(self, credential, auxiliary_credentials=None): | ||||||||||||||||
"""Cross-tenant credential adaptor. It takes a main credential and auxiliary credentials. | ||||||||||||||||
|
||||||||||||||||
It implements Track 2 SDK's azure.core.credentials.TokenCredential by exposing get_token. | ||||||||||||||||
Comment on lines
+12
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Even though Track 1 SDK auth support is dropped, |
||||||||||||||||
|
||||||||||||||||
:param credential: Main credential from .msal_authentication | ||||||||||||||||
:param resource: AAD resource for Track 1 only | ||||||||||||||||
:param auxiliary_credentials: Credentials from .msal_authentication for cross tenant authentication. | ||||||||||||||||
Details about cross tenant authentication: | ||||||||||||||||
https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/authenticate-multi-tenant | ||||||||||||||||
""" | ||||||||||||||||
|
||||||||||||||||
self._credential = credential | ||||||||||||||||
self._auxiliary_credentials = auxiliary_credentials | ||||||||||||||||
self._resource = resource | ||||||||||||||||
|
||||||||||||||||
def _get_token(self, scopes=None, **kwargs): | ||||||||||||||||
external_tenant_tokens = [] | ||||||||||||||||
# If scopes is not provided, use CLI-managed resource | ||||||||||||||||
scopes = scopes or resource_to_scopes(self._resource) | ||||||||||||||||
try: | ||||||||||||||||
token = self._credential.get_token(*scopes, **kwargs) | ||||||||||||||||
if self._auxiliary_credentials: | ||||||||||||||||
external_tenant_tokens = [cred.get_token(*scopes) for cred in self._auxiliary_credentials] | ||||||||||||||||
return token, external_tenant_tokens | ||||||||||||||||
except requests.exceptions.SSLError as err: | ||||||||||||||||
from azure.cli.core.util import SSLERROR_TEMPLATE | ||||||||||||||||
raise CLIError(SSLERROR_TEMPLATE.format(str(err))) | ||||||||||||||||
|
||||||||||||||||
def signed_session(self, session=None): | ||||||||||||||||
logger.debug("CredentialAdaptor.signed_session") | ||||||||||||||||
session = session or requests.Session() | ||||||||||||||||
token, external_tenant_tokens = self._get_token() | ||||||||||||||||
header = "{} {}".format('Bearer', token.token) | ||||||||||||||||
session.headers['Authorization'] = header | ||||||||||||||||
if external_tenant_tokens: | ||||||||||||||||
aux_tokens = ';'.join(['{} {}'.format('Bearer', tokens2.token) for tokens2 in external_tenant_tokens]) | ||||||||||||||||
session.headers['x-ms-authorization-auxiliary'] = aux_tokens | ||||||||||||||||
return session | ||||||||||||||||
|
||||||||||||||||
def get_token(self, *scopes, **kwargs): | ||||||||||||||||
"""Get an access token from the main credential.""" | ||||||||||||||||
logger.debug("CredentialAdaptor.get_token: scopes=%r, kwargs=%r", scopes, kwargs) | ||||||||||||||||
|
||||||||||||||||
# Discard unsupported kwargs: tenant_id, enable_cae | ||||||||||||||||
filtered_kwargs = {} | ||||||||||||||||
if 'data' in kwargs: | ||||||||||||||||
filtered_kwargs['data'] = kwargs['data'] | ||||||||||||||||
|
||||||||||||||||
token, _ = self._get_token(scopes, **filtered_kwargs) | ||||||||||||||||
return token | ||||||||||||||||
return self._credential.get_token(*scopes, **filtered_kwargs) | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I noticed that SSLError try catch part is removed. Any reason? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
azure-cli/src/azure-cli-core/azure/cli/core/util.py Lines 77 to 83 in 05a5d8f
|
||||||||||||||||
|
||||||||||||||||
def get_auxiliary_tokens(self, *scopes, **kwargs): | ||||||||||||||||
"""Get access tokens from auxiliary credentials.""" | ||||||||||||||||
# To test cross-tenant authentication, see https://github.com/Azure/azure-cli/issues/16691 | ||||||||||||||||
if self._auxiliary_credentials: | ||||||||||||||||
return [cred.get_token(*scopes, **kwargs) for cred in self._auxiliary_credentials] | ||||||||||||||||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Track 1 SDK, the
resource
of the access token is managed by Azure CLI, not Track 1 SDK.resource
is kept as a property of the credential returned byget_login_credentials()
. When SDK client callssigned_session()
to acquire the access token, CLI provides the access token forresource
.For Track 2 SDK, the
scopes
(resource/.default
) of the access token is managed by SDK client instead. Thescopes
is passed to Track 2 SDK viacredential_scopes
argument when creating the client instance. The SDK client keeps it and passes it toget_token()
when acquiring the access token from the credential.Since Track 1 SDK is no longer supported, Azure CLI doesn't need to manage
resource
anymore, soresource
argument is dropped.