Skip to content
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

Update Multi-Tenant support to incorporate Arch Board Feedback #20940

Merged
merged 11 commits into from
Oct 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions sdk/identity/azure-identity/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

## 1.7.0b5 (Unreleased)

### Features Added

### Breaking Changes
> These changes do not impact the API of stable versions such as 1.6.0.
> Only code written against a beta version such as 1.7.0b1 may be affected.

xiangyan99 marked this conversation as resolved.
Show resolved Hide resolved
### Bugs Fixed

### Other Changes
- The `allow_multitenant_authentication` argument has been removed and the default behavior is now as if it were true.
The multitenant authentication feature can be totally disabled by setting the environment variable
`AZURE_IDENTITY_DISABLE_MULTITENANTAUTH` to `True`.
- `azure.identity.RegionalAuthority` is removed.
- `regional_authority` argument is removed for `CertificateCredential` and `ClientSecretCredential`

## 1.7.0b4 (2021-09-09)

Expand Down
2 changes: 0 additions & 2 deletions sdk/identity/azure-identity/azure/identity/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"""Credentials for Azure SDK clients."""

from ._auth_record import AuthenticationRecord
from ._enums import RegionalAuthority
from ._exceptions import AuthenticationRequiredError, CredentialUnavailableError
from ._constants import AzureAuthorityHosts, KnownAuthorities
from ._credentials import (
Expand Down Expand Up @@ -47,7 +46,6 @@
"InteractiveBrowserCredential",
"KnownAuthorities",
"OnBehalfOfCredential",
"RegionalAuthority",
"ManagedIdentityCredential",
"SharedTokenCacheCredential",
"TokenCachePersistenceOptions",
Expand Down
2 changes: 1 addition & 1 deletion sdk/identity/azure-identity/azure/identity/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class EnvironmentVariables:
MSI_SECRET = "MSI_SECRET"

AZURE_AUTHORITY_HOST = "AZURE_AUTHORITY_HOST"
AZURE_IDENTITY_ENABLE_LEGACY_TENANT_SELECTION = "AZURE_IDENTITY_ENABLE_LEGACY_TENANT_SELECTION"
AZURE_IDENTITY_DISABLE_MULTITENANTAUTH = "AZURE_IDENTITY_DISABLE_MULTITENANTAUTH"
AZURE_REGIONAL_AUTHORITY_NAME = "AZURE_REGIONAL_AUTHORITY_NAME"

AZURE_FEDERATED_TOKEN_FILE = "AZURE_FEDERATED_TOKEN_FILE"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@ class AzureApplicationCredential(ChainedTokenCredential):
<https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview>`_ for an overview of
managed identities.

:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the application or user is registered in. When False, which is the default, the credential will acquire tokens
only from the tenant specified by **AZURE_TENANT_ID**. This argument doesn't apply to managed identity
authentication.
:keyword str authority: Authority of an Azure Active Directory endpoint, for example "login.microsoftonline.com",
the authority for Azure Public Cloud, which is the default when no value is given for this keyword argument or
environment variable AZURE_AUTHORITY_HOST. :class:`~azure.identity.AzureAuthorityHosts` defines authorities for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ class AuthorizationCodeCredential(GetTokenMixin):
the authority for Azure Public Cloud (which is the default). :class:`~azure.identity.AzureAuthorityHosts`
defines authorities for other clouds.
:keyword str client_secret: One of the application's client secrets. Required only for web apps and web APIs.
:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the user is registered in. When False, which is the default, the credential will acquire tokens only from the
user's home tenant or the tenant specified by **tenant_id**.
"""

def __init__(self, tenant_id, client_id, authorization_code, redirect_uri, **kwargs):
Expand Down Expand Up @@ -67,8 +64,7 @@ def get_token(self, *scopes, **kwargs):
redeeming the authorization code.

:param str scopes: desired scopes for the access token. This method requires at least one scope.
:keyword str tenant_id: optional tenant to include in the token request. If **allow_multitenant_authentication**
is False, specifying a tenant with this argument may raise an exception.
:keyword str tenant_id: optional tenant to include in the token request.

:rtype: :class:`azure.core.credentials.AccessToken`
:raises ~azure.core.exceptions.ClientAuthenticationError: authentication failed. The error's ``message``
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,8 @@ class AzureCliCredential(object):
"""Authenticates by requesting a token from the Azure CLI.

This requires previously logging in to Azure via "az login", and will use the CLI's currently logged in identity.

:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the identity logged in to the Azure CLI is registered in. When False, which is the default, the credential will
acquire tokens only from the tenant of the Azure CLI's active subscription.
"""

def __init__(self, **kwargs):
self._allow_multitenant = kwargs.get("allow_multitenant_authentication", False)

def __enter__(self):
return self

Expand All @@ -55,16 +48,15 @@ def close(self):
"""Calling this method is unnecessary."""

@log_get_token("AzureCliCredential")
def get_token(self, *scopes, **kwargs):
def get_token(self, *scopes, **kwargs): # pylint: disable=no-self-use
# type: (*str, **Any) -> AccessToken
"""Request an access token for `scopes`.

This method is called automatically by Azure SDK clients. Applications calling this method directly must
also handle token caching because this credential doesn't cache the tokens it acquires.

:param str scopes: desired scope for the access token. This credential allows only one scope per request.
:keyword str tenant_id: optional tenant to include in the token request. If **allow_multitenant_authentication**
is False, specifying a tenant with this argument may raise an exception.
:keyword str tenant_id: optional tenant to include in the token request.

:rtype: :class:`azure.core.credentials.AccessToken`

Expand All @@ -75,7 +67,7 @@ def get_token(self, *scopes, **kwargs):

resource = _scopes_to_resource(*scopes)
command = COMMAND_LINE.format(resource)
tenant = resolve_tenant("", self._allow_multitenant, **kwargs)
tenant = resolve_tenant("", **kwargs)
if tenant:
command += " --tenant " + tenant
output = _run_command(command)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,8 @@ class AzurePowerShellCredential(object):
"""Authenticates by requesting a token from Azure PowerShell.

This requires previously logging in to Azure via "Connect-AzAccount", and will use the currently logged in identity.

:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the identity logged in to Azure PowerShell is registered in. When False, which is the default, the credential
will acquire tokens only from the tenant of Azure PowerShell's active subscription.
"""

def __init__(self, **kwargs):
# type: (**Any) -> None
self._allow_multitenant = kwargs.get("allow_multitenant_authentication", False)

def __enter__(self):
return self

Expand All @@ -72,16 +64,15 @@ def close(self):
"""Calling this method is unnecessary."""

@log_get_token("AzurePowerShellCredential")
def get_token(self, *scopes, **kwargs):
def get_token(self, *scopes, **kwargs): # pylint: disable=no-self-use
# type: (*str, **Any) -> AccessToken
"""Request an access token for `scopes`.

This method is called automatically by Azure SDK clients. Applications calling this method directly must
also handle token caching because this credential doesn't cache the tokens it acquires.

:param str scopes: desired scope for the access token. This credential allows only one scope per request.
:keyword str tenant_id: optional tenant to include in the token request. If **allow_multitenant_authentication**
is False, specifying a tenant with this argument may raise an exception.
:keyword str tenant_id: optional tenant to include in the token request.

:rtype: :class:`azure.core.credentials.AccessToken`

Expand All @@ -90,7 +81,7 @@ def get_token(self, *scopes, **kwargs):
:raises ~azure.core.exceptions.ClientAuthenticationError: the credential invoked Azure PowerShell but didn't
receive an access token
"""
tenant_id = resolve_tenant("", self._allow_multitenant, **kwargs)
tenant_id = resolve_tenant("", **kwargs)
command_line = get_command_line(scopes, tenant_id)
output = run_command_line(command_line)
token = parse_token(output)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ class InteractiveBrowserCredential(InteractiveCredential):
will cache tokens in memory.
:paramtype cache_persistence_options: ~azure.identity.TokenCachePersistenceOptions
:keyword int timeout: seconds to wait for the user to complete authentication. Defaults to 300 (5 minutes).
:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the user is registered in. When False, which is the default, the credential will acquire tokens only from the
user's home tenant or the tenant specified by **tenant_id**.
:raises ValueError: invalid **redirect_uri**
"""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,12 @@ class CertificateCredential(ClientCredentialBase):
:keyword password: The certificate's password. If a unicode string, it will be encoded as UTF-8. If the certificate
requires a different encoding, pass appropriately encoded bytes instead.
:paramtype password: str or bytes
:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the application is registered in. When False, which is the default, the credential will acquire tokens only from
the tenant specified by **tenant_id**.
:keyword bool send_certificate_chain: if True, the credential will send the public certificate chain in the x5c
header of each token request's JWT. This is required for Subject Name/Issuer (SNI) authentication. Defaults to
False.
:keyword cache_persistence_options: configuration for persistent token caching. If unspecified, the credential
will cache tokens in memory.
:paramtype cache_persistence_options: ~azure.identity.TokenCachePersistenceOptions
:keyword ~azure.identity.RegionalAuthority regional_authority: a :class:`~azure.identity.RegionalAuthority` to
which the credential will authenticate. This argument should be used only by applications deployed to Azure
VMs.
"""

def __init__(self, tenant_id, client_id, certificate_path=None, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,9 @@ class ClientSecretCredential(ClientCredentialBase):
:keyword str authority: Authority of an Azure Active Directory endpoint, for example "login.microsoftonline.com",
the authority for Azure Public Cloud (which is the default). :class:`~azure.identity.AzureAuthorityHosts`
defines authorities for other clouds.
:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the application is registered in. When False, which is the default, the credential will acquire tokens only from
the tenant specified by **tenant_id**.
:keyword cache_persistence_options: configuration for persistent token caching. If unspecified, the credential
will cache tokens in memory.
:paramtype cache_persistence_options: ~azure.identity.TokenCachePersistenceOptions
:keyword ~azure.identity.RegionalAuthority regional_authority: a :class:`~azure.identity.RegionalAuthority` to
which the credential will authenticate. This argument should be used only by applications deployed to Azure
VMs.
"""

def __init__(self, tenant_id, client_id, client_secret, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ class DefaultAzureCredential(ChainedTokenCredential):

This default behavior is configurable with keyword arguments.

:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the application is registered in. When False, which is the default, the credential will acquire tokens only from
its configured tenant. This argument doesn't apply to managed identity authentication.
:keyword str authority: Authority of an Azure Active Directory endpoint, for example 'login.microsoftonline.com',
the authority for Azure Public Cloud (which is the default). :class:`~azure.identity.AzureAuthorityHosts`
defines authorities for other clouds. Managed identities ignore this because they reside in a single cloud.
Expand Down Expand Up @@ -136,9 +133,9 @@ def __init__(self, **kwargs):
if not exclude_visual_studio_code_credential:
credentials.append(VisualStudioCodeCredential(**vscode_args))
if not exclude_cli_credential:
credentials.append(AzureCliCredential(**kwargs))
credentials.append(AzureCliCredential())
if not exclude_powershell_credential:
credentials.append(AzurePowerShellCredential(**kwargs))
credentials.append(AzurePowerShellCredential())
if not exclude_interactive_browser_credential:
if interactive_browser_client_id:
credentials.append(
Expand All @@ -158,8 +155,7 @@ def get_token(self, *scopes, **kwargs):
This method is called automatically by Azure SDK clients.

:param str scopes: desired scopes for the access token. This method requires at least one scope.
:keyword str tenant_id: optional tenant to include in the token request. If **allow_multitenant_authentication**
is False, specifying a tenant with this argument may raise an exception.
:keyword str tenant_id: optional tenant to include in the token request.

:rtype: :class:`azure.core.credentials.AccessToken`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ class DeviceCodeCredential(InteractiveCredential):
:keyword cache_persistence_options: configuration for persistent token caching. If unspecified, the credential
will cache tokens in memory.
:paramtype cache_persistence_options: ~azure.identity.TokenCachePersistenceOptions
:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the user is registered in. When False, which is the default, the credential will acquire tokens only from the
user's home tenant or the tenant specified by **tenant_id**.
"""

def __init__(self, client_id=DEVELOPER_SIGN_ON_CLIENT_ID, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ class EnvironmentCredential(object):
- **AZURE_TENANT_ID**: (optional) ID of the service principal's tenant. Also called its 'directory' ID.
If not provided, defaults to the 'organizations' tenant, which supports only Azure Active Directory work or
school accounts.

:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the application or user is registered in. When False, which is the default, the credential will acquire tokens
only from the tenant specified by **AZURE_TENANT_ID**.
"""

def __init__(self, **kwargs):
Expand Down Expand Up @@ -123,8 +119,7 @@ def get_token(self, *scopes, **kwargs): # pylint:disable=unused-argument
This method is called automatically by Azure SDK clients.

:param str scopes: desired scopes for the access token. This method requires at least one scope.
:keyword str tenant_id: optional tenant to include in the token request. If **allow_multitenant_authentication**
is False, specifying a tenant with this argument may raise an exception.
:keyword str tenant_id: optional tenant to include in the token request.

:rtype: :class:`azure.core.credentials.AccessToken`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ class OnBehalfOfCredential(MsalCredential, GetTokenMixin):
:param str user_assertion: the access token the credential will use as the user assertion when requesting
on-behalf-of tokens

:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the application is registered in. When False, which is the default, the credential will acquire tokens only
from the tenant specified by **tenant_id**.
:keyword str authority: Authority of an Azure Active Directory endpoint, for example "login.microsoftonline.com",
the authority for Azure Public Cloud (which is the default). :class:`~azure.identity.AzureAuthorityHosts`
defines authorities for other clouds.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ class SharedTokenCacheCredential(object):
:keyword cache_persistence_options: configuration for persistent token caching. If not provided, the credential
will use the persistent cache shared by Microsoft development applications
:paramtype cache_persistence_options: ~azure.identity.TokenCachePersistenceOptions
:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the user is registered in. When False, which is the default, the credential will acquire tokens only from the
user's home tenant or, if a value was given for **authentication_record**, the tenant specified by the
:class:`AuthenticationRecord`.
"""

def __init__(self, username=None, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ def __init__(self, authentication_record, **kwargs):
# authenticate in the tenant that produced the record unless "tenant_id" specifies another
self._tenant_id = kwargs.pop("tenant_id", None) or self._auth_record.tenant_id
validate_tenant_id(self._tenant_id)
self._allow_multitenant = kwargs.pop("allow_multitenant_authentication", False)
self._cache = kwargs.pop("_cache", None)
self._client_applications = {} # type: Dict[str, PublicClientApplication]
self._client = MsalClient(**kwargs)
Expand Down Expand Up @@ -74,7 +73,7 @@ def _initialize(self):
self._initialized = True

def _get_client_application(self, **kwargs):
tenant_id = resolve_tenant(self._tenant_id, self._allow_multitenant, **kwargs)
tenant_id = resolve_tenant(self._tenant_id, **kwargs)
if tenant_id not in self._client_applications:
# CP1 = can handle claims challenges (CAE)
capabilities = None if "AZURE_IDENTITY_DISABLE_CP1" in os.environ else ["CP1"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ class UsernamePasswordCredential(InteractiveCredential):
:keyword cache_persistence_options: configuration for persistent token caching. If unspecified, the credential
will cache tokens in memory.
:paramtype cache_persistence_options: ~azure.identity.TokenCachePersistenceOptions
:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the user is registered in. When False, which is the default, the credential will acquire tokens only from the
user's home tenant or the tenant specified by **tenant_id**.
"""

def __init__(self, client_id, username, password, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,6 @@ class VisualStudioCodeCredential(_VSCodeCredentialBase, GetTokenMixin):
:keyword str tenant_id: ID of the tenant the credential should authenticate in. Defaults to the "Azure: Tenant"
setting in VS Code's user settings or, when that setting has no value, the "organizations" tenant, which
supports only Azure Active Directory work or school accounts.
:keyword bool allow_multitenant_authentication: when True, enables the credential to acquire tokens from any tenant
the user is registered in. When False, which is the default, the credential will acquire tokens only from the
user's home tenant or the tenant configured by **tenant_id** or VS Code's user settings.
"""

def __enter__(self):
Expand Down
Loading