def test_persistent_cache_linux(monkeypatch):
    """Credentials should use an unencrypted cache when encryption is unavailable and the user explicitly opts in.

    This test was written when Linux was the only platform on which encryption may not be available.
    """
    from azure.identity._persistent_cache import _load_persistent_cache

    for cls in ("FilePersistence", "LibsecretPersistence",
                "PersistedTokenCache"):
        monkeypatch.setattr(msal_extensions, cls, mock.Mock())

    _load_persistent_cache(TokenCachePersistenceOptions())
    assert msal_extensions.PersistedTokenCache.called_with(
        msal_extensions.LibsecretPersistence)
    msal_extensions.PersistedTokenCache.reset_mock()

    # when LibsecretPersistence's dependencies aren't available, constructing it raises ImportError
    msal_extensions.LibsecretPersistence = mock.Mock(side_effect=ImportError)

    # encryption unavailable, no unencrypted storage not allowed
    with pytest.raises(ValueError):
        _load_persistent_cache(TokenCachePersistenceOptions())

    # encryption unavailable, unencrypted storage allowed
    _load_persistent_cache(
        TokenCachePersistenceOptions(allow_unencrypted_storage=True))
    msal_extensions.PersistedTokenCache.called_with(
        msal_extensions.FilePersistence)
Ejemplo n.º 2
0
def test_persistent_cache_multiple_clients(cert_path, cert_password):
    """the credential shouldn't use tokens issued to other service principals"""

    access_token_a = "token a"
    access_token_b = "not " + access_token_a
    transport_a = msal_validating_transport(
        requests=[Request()],
        responses=[
            mock_response(json_payload=build_aad_response(
                access_token=access_token_a))
        ])
    transport_b = msal_validating_transport(
        requests=[Request()],
        responses=[
            mock_response(json_payload=build_aad_response(
                access_token=access_token_b))
        ])

    cache = TokenCache()
    with patch(
            "azure.identity._internal.msal_credentials._load_persistent_cache"
    ) as mock_cache_loader:
        mock_cache_loader.return_value = Mock(wraps=cache)
        credential_a = CertificateCredential(
            "tenant",
            "client-a",
            cert_path,
            password=cert_password,
            transport=transport_a,
            cache_persistence_options=TokenCachePersistenceOptions(),
        )
        assert mock_cache_loader.call_count == 1, "credential should load the persistent cache"

        credential_b = CertificateCredential(
            "tenant",
            "client-b",
            cert_path,
            password=cert_password,
            transport=transport_b,
            cache_persistence_options=TokenCachePersistenceOptions(),
        )
        assert mock_cache_loader.call_count == 2, "credential should load the persistent cache"

    # A caches a token
    scope = "scope"
    token_a = credential_a.get_token(scope)
    assert token_a.token == access_token_a
    assert transport_a.send.call_count == 3  # two MSAL discovery requests, one token request

    # B should get a different token for the same scope
    token_b = credential_b.get_token(scope)
    assert token_b.token == access_token_b
    assert transport_b.send.call_count == 3

    assert len(cache.find(TokenCache.CredentialType.ACCESS_TOKEN)) == 2
Ejemplo n.º 3
0
def test_token_cache_persistence_options():
    with mock.patch("azure.identity._persistent_cache.msal_extensions"):
        # [START snippet]
        cache_options = TokenCachePersistenceOptions()
        credential = InteractiveBrowserCredential(
            cache_persistence_options=cache_options)

        # specify a cache name to isolate the cache from other applications
        TokenCachePersistenceOptions(name="my_application")

        # configure the cache to fall back to unencrypted storage when encryption isn't available
        TokenCachePersistenceOptions(allow_unencrypted_storage=True)
Ejemplo n.º 4
0
async def test_cache_multiple_clients():
    """the credential shouldn't use tokens issued to other service principals"""

    access_token_a = "token a"
    access_token_b = "not " + access_token_a
    transport_a = async_validating_transport(
        requests=[Request()],
        responses=[
            mock_response(json_payload=build_aad_response(
                access_token=access_token_a))
        ])
    transport_b = async_validating_transport(
        requests=[Request()],
        responses=[
            mock_response(json_payload=build_aad_response(
                access_token=access_token_b))
        ])

    cache = TokenCache()
    with patch(ClientSecretCredential.__module__ +
               "._load_persistent_cache") as mock_cache_loader:
        mock_cache_loader.return_value = Mock(wraps=cache)
        credential_a = ClientSecretCredential(
            "tenant",
            "client-a",
            "secret",
            transport=transport_a,
            cache_persistence_options=TokenCachePersistenceOptions(),
        )
        assert mock_cache_loader.call_count == 1, "credential should load the persistent cache"

        credential_b = ClientSecretCredential(
            "tenant",
            "client-b",
            "secret",
            transport=transport_b,
            cache_persistence_options=TokenCachePersistenceOptions(),
        )
        assert mock_cache_loader.call_count == 2, "credential should load the persistent cache"

    # A caches a token
    scope = "scope"
    token_a = await credential_a.get_token(scope)
    assert token_a.token == access_token_a
    assert transport_a.send.call_count == 1

    # B should get a different token for the same scope
    token_b = await credential_b.get_token(scope)
    assert token_b.token == access_token_b
    assert transport_b.send.call_count == 1

    assert len(cache.find(TokenCache.CredentialType.ACCESS_TOKEN)) == 2
    def __init__(self, arguments):
        super().__init__(arguments)

        client_id = self.get_from_env("AZURE_CLIENT_ID")
        tenant_id = self.get_from_env("AZURE_TENANT_ID")
        secret = self.get_from_env("AZURE_CLIENT_SECRET")
        self.credential = ClientSecretCredential(
            tenant_id,
            client_id,
            secret,
            cache_persistence_options=TokenCachePersistenceOptions())
        self.async_credential = AsyncClientSecretCredential(
            tenant_id,
            client_id,
            secret,
            cache_persistence_options=TokenCachePersistenceOptions())
        self.scope = "https://vault.azure.net/.default"
Ejemplo n.º 6
0
def _get_cache_args(token_path: Path):
    cache_args = {
        'cache_persistence_options':
        TokenCachePersistenceOptions(name='parsedmarc')
    }
    auth_record = _load_token(token_path)
    if auth_record:
        cache_args['authentication_record'] = \
            AuthenticationRecord.deserialize(auth_record)
    return cache_args
Ejemplo n.º 7
0
def test_token_cache():
    """the credential should default to an in memory cache, and optionally use a persistent cache"""

    with patch("azure.identity._persistent_cache.msal_extensions") as mock_msal_extensions:
        credential = ClientSecretCredential("tenant", "client-id", "secret")
        assert not mock_msal_extensions.PersistedTokenCache.called
        assert isinstance(credential._cache, TokenCache)

        ClientSecretCredential(
            "tenant", "client-id", "secret", cache_persistence_options=TokenCachePersistenceOptions()
        )
        assert mock_msal_extensions.PersistedTokenCache.call_count == 1
def test_token_cache():
    """the credential should default to an in memory cache, and optionally use a persistent cache"""

    with patch(ClientSecretCredential.__module__ + "._load_persistent_cache") as load_persistent_cache:
        with patch(ClientSecretCredential.__module__ + ".msal") as mock_msal:
            ClientSecretCredential("tenant", "client-id", "secret")
        assert mock_msal.TokenCache.call_count == 1
        assert not load_persistent_cache.called

        ClientSecretCredential(
            "tenant", "client-id", "secret", cache_persistence_options=TokenCachePersistenceOptions()
        )
        assert load_persistent_cache.call_count == 1
Ejemplo n.º 9
0
def test_token_cache(cert_path, cert_password):
    """the credential should optionally use a persistent cache, and default to an in memory cache"""

    with patch("azure.identity._internal.msal_credentials._load_persistent_cache") as load_persistent_cache:
        credential = CertificateCredential("tenant", "client-id", cert_path, password=cert_password)
        assert not load_persistent_cache.called
        assert isinstance(credential._cache, TokenCache)

        CertificateCredential(
            "tenant",
            "client-id",
            cert_path,
            password=cert_password,
            cache_persistence_options=TokenCachePersistenceOptions(),
        )
        assert load_persistent_cache.call_count == 1
Ejemplo n.º 10
0
def test_token_cache(cert_path, cert_password):
    """the credential should optionally use a persistent cache, and default to an in memory cache"""

    with patch(CertificateCredential.__module__ + "._load_persistent_cache") as load_persistent_cache:
        with patch(CertificateCredential.__module__ + ".msal") as mock_msal:
            CertificateCredential("tenant", "client-id", cert_path, password=cert_password)
        assert mock_msal.TokenCache.call_count == 1
        assert not load_persistent_cache.called

        CertificateCredential(
            "tenant",
            "client-id",
            cert_path,
            password=cert_password,
            cache_persistence_options=TokenCachePersistenceOptions(),
        )
        assert load_persistent_cache.call_count == 1
def test_token_cache():
    """the credential should default to an in memory cache, and optionally use a persistent cache"""

    class TestCredential(InteractiveCredential):
        def __init__(self, **kwargs):
            super(TestCredential, self).__init__(client_id="...", **kwargs)

        def _request_token(self, *_, **__):
            pass

    with patch("azure.identity._persistent_cache.msal_extensions") as mock_msal_extensions:
        with patch("azure.identity._internal.msal_credentials.msal") as mock_msal:
            TestCredential()
        assert not mock_msal_extensions.PersistedTokenCache.called
        assert mock_msal.TokenCache.call_count == 1

        TestCredential(cache_persistence_options=TokenCachePersistenceOptions())
        assert mock_msal_extensions.PersistedTokenCache.call_count == 1
from azure.identity import AuthenticationRecord, InteractiveBrowserCredential, TokenCachePersistenceOptions
from azure.keyvault.secrets import SecretClient

# This sample uses Key Vault only for demonstration. Any client accepting azure-identity credentials will work the same.
VAULT_URL = os.environ.get("VAULT_URL")
if not VAULT_URL:
    print(
        "This sample expects environment variable 'VAULT_URL' to be set with the URL of a Key Vault."
    )
    sys.exit(1)

# Persistent caching is optional. By default, interactive credentials cache in memory only.
# To enable persistent caching, give the credential an instance of TokenCachePersistenceOptions.
# (see the API documentation for more information about TokenCachePersistenceOptions)
credential = InteractiveBrowserCredential(
    cache_persistence_options=TokenCachePersistenceOptions())

# The 'authenticate' method begins interactive authentication. Call it whenever it's convenient
# for your application to authenticate a user. It returns a record of the authentication.
record = credential.authenticate()
print("\nAuthenticated first credential")

# The record contains no authentication secrets. You can serialize it to JSON for storage.
record_json = record.serialize()

# An authenticated credential is ready for use with a client. This request should succeed
# without prompting for authentication again.
client = SecretClient(VAULT_URL, credential)
secret_names = [s.name for s in client.list_properties_of_secrets()]
print("\nCompleted request with first credential")
from azure.identity import AuthenticationRecord, InteractiveBrowserCredential, TokenCachePersistenceOptions
from azure.keyvault.secrets import SecretClient

# This sample uses Key Vault only for demonstration. Any client accepting azure-identity credentials will work the same.
VAULT_URL = os.environ.get("VAULT_URL")
if not VAULT_URL:
    print(
        "This sample expects environment variable 'VAULT_URL' to be set with the URL of a Key Vault."
    )
    sys.exit(1)

# Persistent caching is optional. By default, interactive credentials cache in memory only.
# To enable persistent caching, give the credential an instance of TokenCachePersistenceOptions.
# (see the API documentation for more information about TokenCachePersistenceOptions)
credential = InteractiveBrowserCredential(
    cache_persistence_options=TokenCachePersistenceOptions())

# The 'authenticate' method begins interactive authentication. Call it whenever it's convenient
# for your application to authenticate a user. It returns a record of the authentication.
record = credential.authenticate()

# The record contains no authentication secrets. You can serialize it to JSON for storage.
record_json = record.serialize()

# An authenticated credential is ready for use with a client. This request should succeed
# without prompting for authentication again.
client = SecretClient(VAULT_URL, credential)
secret_names = [s.name for s in client.list_properties_of_secrets()]

# An authentication record stored by your application enables other credentials to access data from
# past authentications. If the cache contains sufficient data, this eliminates the need for your