コード例 #1
0
def get_azure_token():
    credential_chain = ChainedTokenCredential(ManagedIdentityCredential(), AzureCliCredential())
    try:
        token = credential_chain.get_token("https://monitoring.azure.com//.default")
        return token.token
    except Exception as e:
        logging.exception(f"Failed to retrieve Azure token. Reason is {type(e).__name__} {e}")
        return None
コード例 #2
0
def test_chain_returns_first_token():
    expected_token = Mock()
    first_credential = Mock(get_token=lambda _: expected_token)
    second_credential = Mock(get_token=Mock())

    aggregate = ChainedTokenCredential(first_credential, second_credential)
    credential = aggregate.get_token("scope")

    assert credential is expected_token
    assert second_credential.get_token.call_count == 0
コード例 #3
0
def test_close():
    credentials = [MagicMock(close=Mock()) for _ in range(5)]
    chain = ChainedTokenCredential(*credentials)

    for credential in credentials:
        assert credential.__exit__.call_count == 0

    chain.close()

    for credential in credentials:
        assert credential.__exit__.call_count == 1
コード例 #4
0
ファイル: azure.py プロジェクト: JordanSimba/dvc
    def __init__(self, repo, config):
        super().__init__(repo, config)

        self._account_url = None
        url = config.get("url", "azure://")
        self.path_info = self.PATH_CLS(url)
        self.bucket = self.path_info.bucket

        if not self.bucket:
            container = self._az_config.get("storage", "container_name", None)
            self.path_info = self.PATH_CLS(f"azure://{container}")
            self.bucket = self.path_info.bucket

        self._conn_str = config.get(
            "connection_string") or self._az_config.get(
                "storage", "connection_string", None)

        if not self._conn_str:
            name = config.get("storage_account") or self._az_config.get(
                "storage", "account", None)
            self._account_url = f"https://{name}.blob.core.windows.net"

        # Microsoft azure docs
        # https://docs.microsoft.com/en-us/python/api/overview/azure/identity-readme?view=azure-python
        self._credential = (config.get("sas_token")
                            or config.get("storage_key")
                            or self._az_config.get("storage", "key", None) or
                            self._az_config.get("storage", "sas_token", None)
                            or ChainedTokenCredential(
                                ServicePrincipalConfigCredential(config),
                                DefaultAzureCredential(),
                            ))
コード例 #5
0
    def __init__(self, synapse_dev_url: str, pool_name: str, datalake_dir: str,
                 executor_size: str, executors: int):
        tenant_id = '72f988bf-86f1-41af-91ab-2d7cd011db47'
        authority_host_uri = 'login.microsoftonline.com'
        client_id = '04b07795-8ddb-461a-bbee-02f9e1bf7b46'

        global login_credential_cache
        # use a global cache to store the credential, to avoid users from multiple login

        if login_credential_cache is None:
            # use DeviceCodeCredential if EnvironmentCredential is not available
            self.credential = ChainedTokenCredential(
                EnvironmentCredential(),
                DeviceCodeCredential(client_id,
                                     authority=authority_host_uri,
                                     tenant=tenant_id))
            login_credential_cache = self.credential
        else:
            self.credential = login_credential_cache

        self._api = SynapseJobRunner(synapse_dev_url,
                                     pool_name,
                                     executor_size=executor_size,
                                     executors=executors,
                                     credential=self.credential)
        self._datalake = DataLakeFiler(datalake_dir,
                                       credential=self.credential)
コード例 #6
0
    def _default_chained_credentials(self) -> ChainedTokenCredential:
        managed_identity = ManagedIdentityCredential()
        azure_cli = AzureCliCredential()
        environment = EnvironmentCredential()
        shared_token_cache = SharedTokenCacheCredential()
        interactive_browser = InteractiveBrowserCredential()

        return ChainedTokenCredential(managed_identity, azure_cli, environment, shared_token_cache, interactive_browser)
コード例 #7
0
def test_chain_attempts_all_credentials():
    expected_token = AccessToken("expected_token", 0)

    credentials = [
        Mock(get_token=Mock(side_effect=CredentialUnavailableError(message=""))),
        Mock(get_token=Mock(side_effect=CredentialUnavailableError(message=""))),
        Mock(get_token=Mock(return_value=expected_token)),
    ]

    token = ChainedTokenCredential(*credentials).get_token("scope")
    assert token is expected_token

    for credential in credentials:
        assert credential.get_token.call_count == 1
コード例 #8
0
def test_credential_chain_error_message():
    def raise_authn_error(message):
        raise ClientAuthenticationError(message)

    first_error = "first_error"
    first_credential = Mock(spec=ClientSecretCredential, get_token=lambda _: raise_authn_error(first_error))
    second_error = "second_error"
    second_credential = Mock(name="second_credential", get_token=lambda _: raise_authn_error(second_error))

    with pytest.raises(ClientAuthenticationError) as ex:
        ChainedTokenCredential(first_credential, second_credential).get_token("scope")

    assert "ClientSecretCredential" in ex.value.message
    assert first_error in ex.value.message
    assert second_error in ex.value.message
コード例 #9
0
def test_chain_raises_for_unexpected_error():
    """the chain should not continue after an unexpected error (i.e. anything but CredentialUnavailableError)"""

    expected_message = "it can't be done"

    credentials = [
        Mock(get_token=Mock(side_effect=CredentialUnavailableError(message=""))),
        Mock(get_token=Mock(side_effect=ValueError(expected_message))),
        Mock(get_token=Mock(return_value=AccessToken("**", 42))),
    ]

    with pytest.raises(ClientAuthenticationError) as ex:
        ChainedTokenCredential(*credentials).get_token("scope")

    assert expected_message in ex.value.message
    assert credentials[-1].get_token.call_count == 0
コード例 #10
0
def test_credential_chain_error_message():
    first_error = "first_error"
    first_credential = Mock(
        spec=ClientSecretCredential, get_token=Mock(side_effect=CredentialUnavailableError(first_error))
    )
    second_error = "second_error"
    second_credential = Mock(
        name="second_credential", get_token=Mock(side_effect=ClientAuthenticationError(second_error))
    )

    with pytest.raises(ClientAuthenticationError) as ex:
        ChainedTokenCredential(first_credential, second_credential).get_token("scope")

    assert "ClientSecretCredential" in ex.value.message
    assert first_error in ex.value.message
    assert second_error in ex.value.message
コード例 #11
0
def test_context_manager():
    credentials = [MagicMock() for _ in range(5)]
    chain = ChainedTokenCredential(*credentials)

    for credential in credentials:
        assert credential.__enter__.call_count == 0
        assert credential.__exit__.call_count == 0

    with chain:
        for credential in credentials:
            assert credential.__enter__.call_count == 1
            assert credential.__exit__.call_count == 0

    for credential in credentials:
        assert credential.__enter__.call_count == 1
        assert credential.__exit__.call_count == 1
コード例 #12
0
def test_chain_attempts_all_credentials():
    def raise_authn_error(message="it didn't work"):
        raise ClientAuthenticationError(message)

    expected_token = AccessToken("expected_token", 0)

    credentials = [
        Mock(get_token=Mock(wraps=raise_authn_error)),
        Mock(get_token=Mock(wraps=raise_authn_error)),
        Mock(get_token=Mock(return_value=expected_token)),
    ]

    token = ChainedTokenCredential(*credentials).get_token("scope")
    assert token is expected_token

    for credential in credentials:
        assert credential.get_token.call_count == 1
コード例 #13
0
)
from azure.storage.queue import QueueServiceClient
from azure.ai.formrecognizer import FormRecognizerClient
from azure.ai.textanalytics import TextAnalyticsClient
from azure.cosmos import CosmosClient

from smart_getenv import getenv
from dotmap import DotMap
from dotenv import load_dotenv, find_dotenv

load_dotenv(find_dotenv())

sleep = getenv("AZURE_STORAGE_QUEUE_RECEIVE_SLEEP", type=bool, default=1)

credential = ChainedTokenCredential(AzureCliCredential(),
                                    EnvironmentCredential(),
                                    ManagedIdentityCredential())

queue_service_client = QueueServiceClient(
    account_url=getenv("AZURE_STORAGE_QUEUE_ENDPOINT"), credential=credential)

queue_client = queue_service_client.get_queue_client(
    queue=getenv("AZURE_STORAGE_QUEUE_NAME", default="messages"))

fr_client = FormRecognizerClient(
    endpoint=getenv("AZURE_FORM_RECOGNIZER_ENDPOINT"), credential=credential)

ta_client = TextAnalyticsClient(
    endpoint=getenv("AZURE_TEXT_ANALYTICS_ENDPOINT"), credential=credential)

cosmos_client = CosmosClient(url=getenv("AZURE_COSMOS_ENDPOINT"),
コード例 #14
0
from azure.core.exceptions import HttpResponseError

# Run run.get.secret.ps1 to initialize environment variables and run the app
"""
Manual: 
In Windows, using PowerShell, you can get and set temporary environment vars 
thusly: 
    set: $env:VAULT_URL="https://keyvault-pythonqs-kv.vault.azure.net/"
    get: $env:VAULT_URL
In Linux: 
    set: export VAULT_URL="https://keyvault-pythonqs-kv.vault.azure.net/"
    get: echo $VAULT_URL

"""
VAULT_URL = os.environ["VAULT_URL"]
SECRET_NAME = os.environ["SECRET_NAME"]
# credential = DefaultAzureCredential()
# This seems to work better:
# https://docs.microsoft.com/en-us/answers/questions/74848/access-denied-to-first-party-service.html
credential = ChainedTokenCredential(AzureCliCredential())
client = SecretClient(vault_url=VAULT_URL, credential=credential)

try:
    # Let's get the secret using its name
    print("\n.. Get a Secret by name")
    the_secret = client.get_secret(SECRET_NAME)
    print("Secret with name '{0}' was found with value '{1}'.".format(
        the_secret.name, the_secret.value))
except HttpResponseError as e:
    print("\nThis sample has caught an error. {0}".format(e.message))
コード例 #15
0
def az_connect_core(auth_methods: List[str] = None,
                    silent: bool = False) -> AzCredentials:
    """
    Authenticate using multiple authentication sources.

    Parameters
    ----------
    auth_methods
        List of authentication methods to try
        Possible options are:
        - "env" - to get authentication details from environment varibales
        - "cli" - to use Azure CLI authentication details
        - "msi" - to user Managed Service Indenity details
        - "interactive" - to prompt for interactive login
        Default is ["env", "cli", "msi", "interactive"]

    silent
        Whether to display any output during auth process. Default is False.

    Returns
    -------
    AzCredentials
        Named tuple of:
        - legacy (ADAL) credentials
        - modern (MSAL) credentials

    Raises
    ------
    CloudError
        If chained token credential creation fails.
    MsticpyAzureConnectionError
        If invalid auth options are presented.

    Notes
    -----
    The function tries to obtain credentials from the following
    sources:
    - Azure Auth Environment variables
    - Azure CLI (if an active session is logged on)
    - Managed Service Identity
    - Interactive browser logon
    If the authentication is successful both ADAL (legacy) and
    MSAL (modern) credential types are returned.

    """
    if not auth_methods:
        auth_methods = default_auth_methods()
    try:
        auths = [_AUTH_OPTIONS[meth] for meth in auth_methods]
    except KeyError as err:
        raise MsticpyAzureConnectionError(
            "Unknown authentication option, valid options are; env, cli, msi, interactive"
        ) from err

    # Filter and replace error message when credentials not found
    handler = logging.StreamHandler(sys.stdout)
    if silent:
        handler.addFilter(_filter_all_warnings)
    else:
        handler.addFilter(_filter_credential_warning)
    logging.basicConfig(level=logging.WARNING, handlers=[handler])

    # Create credentials and connect to the subscription client to validate
    creds = ChainedTokenCredential(*auths)
    legacy_creds = CredentialWrapper(creds)
    if not creds:
        raise CloudError("Could not obtain credentials.")

    return AzCredentials(legacy_creds, creds)