Exemplo n.º 1
0
async 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 = 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("azure.identity._internal.persistent_cache._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, enable_persistent_cache=True, transport=transport_a
        )
        assert mock_cache_loader.call_count == 1, "credential should load the persistent cache"
        credential_b = CertificateCredential(
            "tenant", "client-b", cert_path, password=cert_password, enable_persistent_cache=True, transport=transport_b
        )
        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
def test_user_agent():
    client_id = "client-id"
    transport = validating_transport(
        requests=[Request()] * 2 +
        [Request(required_headers={"User-Agent": USER_AGENT})],
        responses=[
            get_discovery_response(),
            mock_response(
                json_payload={
                    "device_code": "_",
                    "user_code": "user-code",
                    "verification_uri": "verification-uri",
                    "expires_in": 42,
                }),
            mock_response(json_payload=dict(build_aad_response(
                access_token="**", id_token=build_id_token(aud=client_id)),
                                            scope="scope")),
        ],
    )

    credential = DeviceCodeCredential(client_id=client_id,
                                      prompt_callback=Mock(),
                                      transport=transport,
                                      _cache=TokenCache())

    credential.get_token("scope")
Exemplo n.º 3
0
 def __init__(self, tenant_id, client_id, authority=None, cache=None, **kwargs):
     # type: (str, str, Optional[str], Optional[TokenCache], **Any) -> None
     authority = normalize_authority(authority) if authority else get_default_authority()
     self._token_endpoint = "/".join((authority, tenant_id, "oauth2/v2.0/token"))
     self._cache = cache or TokenCache()
     self._client_id = client_id
     self._pipeline = self._build_pipeline(**kwargs)
    def __init__(self, tenant_id, client_id, certificate_path, **kwargs):
        # type: (str, str, str, **Any) -> None
        if not certificate_path:
            raise ValueError(
                "'certificate_path' must be the path to a PEM file containing an x509 certificate and its private key"
            )

        super(CertificateCredentialBase, self).__init__()

        password = kwargs.pop("password", None)
        if isinstance(password, six.text_type):
            password = password.encode(encoding="utf-8")

        with open(certificate_path, "rb") as f:
            pem_bytes = f.read()

        self._certificate = AadClientCertificate(pem_bytes, password=password)

        enable_persistent_cache = kwargs.pop("_enable_persistent_cache", False)
        if enable_persistent_cache:
            allow_unencrypted = kwargs.pop("_allow_unencrypted_cache", False)
            cache = load_service_principal_cache(allow_unencrypted)
        else:
            cache = TokenCache()

        self._client = self._get_auth_client(tenant_id,
                                             client_id,
                                             cache=cache,
                                             **kwargs)
        self._client_id = client_id
def test_interactive_credential_timeout():
    # mock transport handles MSAL's tenant discovery
    transport = Mock(send=lambda _, **__: mock_response(
        json_payload={
            "authorization_endpoint": "https://a/b",
            "token_endpoint": "https://a/b"
        }))

    # mock local server blocks long enough to exceed the timeout
    timeout = 0.01
    server_instance = Mock(
        wait_for_redirect=functools.partial(time.sleep, timeout + 0.01))
    server_class = Mock(return_value=server_instance)

    credential = InteractiveBrowserCredential(
        client_id="guid",
        _server_class=server_class,
        timeout=timeout,
        transport=transport,
        instance_discovery=
        False,  # kwargs are passed to MSAL; this one prevents an AAD verification request
        _cache=TokenCache(),
    )

    with pytest.raises(ClientAuthenticationError) as ex:
        credential.get_token("scope")
    assert "timed out" in ex.value.message.lower()
Exemplo n.º 6
0
def test_timeout():
    """get_token should raise ClientAuthenticationError when the server times out without receiving a redirect"""

    timeout = 0.01

    class GuaranteedTimeout(AuthCodeRedirectServer, object):
        def handle_request(self):
            time.sleep(timeout + 0.01)
            super(GuaranteedTimeout, self).handle_request()

    # mock transport handles MSAL's tenant discovery
    transport = Mock(send=lambda _, **__: mock_response(
        json_payload={
            "authorization_endpoint": "https://a/b",
            "token_endpoint": "https://a/b"
        }))

    credential = InteractiveBrowserCredential(timeout=timeout,
                                              transport=transport,
                                              _cache=TokenCache(),
                                              _server_class=GuaranteedTimeout)

    with patch(WEBBROWSER_OPEN, lambda _: True):
        with pytest.raises(ClientAuthenticationError) as ex:
            credential.get_token("scope")
    assert "timed out" in ex.value.message.lower()
Exemplo n.º 7
0
def test_policies_configurable():
    policy = Mock(spec_set=SansIOHTTPPolicy, on_request=Mock())

    transport = validating_transport(
        requests=[Request()] * 3,
        responses=[
            # expected requests: discover tenant, start device code flow, poll for completion
            get_discovery_response(),
            mock_response(
                json_payload={
                    "device_code": "_",
                    "user_code": "user-code",
                    "verification_uri": "verification-uri",
                    "expires_in": 42,
                }),
            mock_response(json_payload=dict(
                build_aad_response(access_token="**"), scope="scope")),
        ],
    )

    credential = DeviceCodeCredential(client_id="client-id",
                                      prompt_callback=Mock(),
                                      policies=[policy],
                                      transport=transport,
                                      _cache=TokenCache())

    credential.get_token("scope")

    assert policy.on_request.called
Exemplo n.º 8
0
def test_timeout():
    transport = validating_transport(
        requests=[Request()] *
        3,  # not validating requests because they're formed by MSAL
        responses=[
            # expected requests: discover tenant, start device code flow, poll for completion
            mock_response(
                json_payload={
                    "authorization_endpoint": "https://a/b",
                    "token_endpoint": "https://a/b"
                }),
            mock_response(json_payload={
                "device_code": "_",
                "user_code": "_",
                "verification_uri": "_"
            }),
            mock_response(json_payload={"error": "authorization_pending"}),
        ],
    )

    credential = DeviceCodeCredential(
        client_id="_",
        prompt_callback=Mock(),
        transport=transport,
        timeout=0.01,
        instance_discovery=False,
        _cache=TokenCache(),
    )

    with pytest.raises(ClientAuthenticationError) as ex:
        credential.get_token("scope")
    assert "timed out" in ex.value.message.lower()
def test_no_browser():
    transport = validating_transport(requests=[Request()] * 2, responses=[get_discovery_response()] * 2)
    credential = InteractiveBrowserCredential(
        client_id="client-id", _server_class=Mock(), transport=transport, _cache=TokenCache()
    )
    with pytest.raises(ClientAuthenticationError, match=r".*browser.*"):
        credential.get_token("scope")
    def __init__(self, tenant_id, client_id, client_secret, **kwargs):
        # type: (str, str, str, **Any) -> None
        if not client_id:
            raise ValueError(
                "client_id should be the id of an Azure Active Directory application"
            )
        if not client_secret:
            raise ValueError(
                "secret should be an Azure Active Directory application's client secret"
            )
        if not tenant_id:
            raise ValueError(
                "tenant_id should be an Azure Active Directory tenant's id (also called its 'directory id')"
            )
        validate_tenant_id(tenant_id)

        enable_persistent_cache = kwargs.pop("enable_persistent_cache", False)
        if enable_persistent_cache:
            allow_unencrypted = kwargs.pop("allow_unencrypted_cache", False)
            cache = load_service_principal_cache(allow_unencrypted)
        else:
            cache = TokenCache()

        self._client = self._get_auth_client(tenant_id,
                                             client_id,
                                             cache=cache,
                                             **kwargs)
        self._client_id = client_id
        self._secret = client_secret
def test_device_code_credential():
    client_id = "client-id"
    expected_token = "access-token"
    user_code = "user-code"
    verification_uri = "verification-uri"
    expires_in = 42

    transport = validating_transport(
        requests=[Request()] *
        3,  # not validating requests because they're formed by MSAL
        responses=[
            # expected requests: discover tenant, start device code flow, poll for completion
            mock_response(
                json_payload={
                    "authorization_endpoint": "https://a/b",
                    "token_endpoint": "https://a/b"
                }),
            mock_response(
                json_payload={
                    "device_code": "_",
                    "user_code": user_code,
                    "verification_uri": verification_uri,
                    "expires_in": expires_in,
                }),
            mock_response(json_payload=dict(
                build_aad_response(
                    access_token=expected_token,
                    expires_in=expires_in,
                    refresh_token="_",
                    id_token=build_id_token(aud=client_id),
                ),
                scope="scope",
            ), ),
        ],
    )

    callback = Mock()
    credential = DeviceCodeCredential(
        client_id=client_id,
        prompt_callback=callback,
        transport=transport,
        instance_discovery=False,
        _cache=TokenCache(),
    )

    now = datetime.datetime.utcnow()
    token = credential.get_token("scope")
    assert token.token == expected_token

    # prompt_callback should have been called as documented
    assert callback.call_count == 1
    uri, code, expires_on = callback.call_args[0]
    assert uri == verification_uri
    assert code == user_code

    # validating expires_on exactly would require depending on internals of the credential and
    # patching time, so we'll be satisfied if expires_on is a datetime at least expires_in
    # seconds later than our call to get_token
    assert isinstance(expires_on, datetime.datetime)
    assert expires_on - now >= datetime.timedelta(seconds=expires_in)
def test_policies_configurable():
    policy = Mock(spec_set=SansIOHTTPPolicy, on_request=Mock())
    client_id = "client-id"
    transport = validating_transport(
        requests=[Request()] * 2,
        responses=[
            get_discovery_response(),
            mock_response(json_payload=build_aad_response(
                access_token="**", id_token=build_id_token(aud=client_id))),
        ],
    )

    # mock local server fakes successful authentication by immediately returning a well-formed response
    oauth_state = "oauth-state"
    auth_code_response = {"code": "authorization-code", "state": [oauth_state]}
    server_class = Mock(return_value=Mock(
        wait_for_redirect=lambda: auth_code_response))

    credential = InteractiveBrowserCredential(policies=[policy],
                                              client_id=client_id,
                                              transport=transport,
                                              _server_class=server_class,
                                              _cache=TokenCache())

    with patch("azure.identity._credentials.browser.uuid.uuid4",
               lambda: oauth_state):
        credential.get_token("scope")

    assert policy.on_request.called
def test_user_agent():
    client_id = "client-id"
    transport = validating_transport(
        requests=[
            Request(),
            Request(required_headers={"User-Agent": USER_AGENT})
        ],
        responses=[
            get_discovery_response(),
            mock_response(json_payload=build_aad_response(
                access_token="**", id_token=build_id_token(aud=client_id))),
        ],
    )

    # mock local server fakes successful authentication by immediately returning a well-formed response
    oauth_state = "oauth-state"
    auth_code_response = {"code": "authorization-code", "state": [oauth_state]}
    server_class = Mock(return_value=Mock(
        wait_for_redirect=lambda: auth_code_response))

    credential = InteractiveBrowserCredential(client_id=client_id,
                                              transport=transport,
                                              _server_class=server_class,
                                              _cache=TokenCache())

    with patch("azure.identity._credentials.browser.uuid.uuid4",
               lambda: oauth_state):
        credential.get_token("scope")
Exemplo n.º 14
0
def test_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
def test_authenticate():
    client_id = "client-id"
    environment = "localhost"
    issuer = "https://" + environment
    tenant_id = "some-tenant"
    authority = issuer + "/" + tenant_id

    access_token = "***"
    scope = "scope"

    # mock AAD response with id token
    object_id = "object-id"
    home_tenant = "home-tenant-id"
    username = "******"
    id_token = build_id_token(aud=client_id,
                              iss=issuer,
                              object_id=object_id,
                              tenant_id=home_tenant,
                              username=username)
    auth_response = build_aad_response(uid=object_id,
                                       utid=home_tenant,
                                       access_token=access_token,
                                       refresh_token="**",
                                       id_token=id_token)

    transport = validating_transport(
        requests=[Request(url_substring=issuer)] * 4,
        responses=[get_discovery_response(authority)] * 2  # instance and tenant discovery
        + [
            mock_response(  # start device code flow
                json_payload={
                    "device_code": "_",
                    "user_code": "user-code",
                    "verification_uri": "verification-uri",
                    "expires_in": 42,
                }
            ),
            mock_response(json_payload=dict(auth_response, scope=scope)),  # poll for completion
        ],
    )

    credential = DeviceCodeCredential(
        client_id,
        prompt_callback=Mock(),  # prevent credential from printing to stdout
        transport=transport,
        authority=environment,
        tenant_id=tenant_id,
        _cache=TokenCache(),
    )
    record = credential.authenticate(scopes=(scope, ))

    # credential should have a cached access token for the scope used in authenticate
    token = credential.get_token(scope)
    assert token.token == access_token

    assert record.authority == environment
    assert record.home_account_id == object_id + "." + home_tenant
    assert record.tenant_id == home_tenant
    assert record.username == username
Exemplo n.º 16
0
def test_authority(authority):
    """the credential should accept an authority, with or without scheme, as an argument or environment variable"""

    parsed_authority = urlparse(authority)
    expected_netloc = parsed_authority.netloc or authority  # "localhost" parses to netloc "", path "localhost"

    class MockCredential(SharedTokenCacheCredential):
        def _get_auth_client(self, authority=None, **kwargs):
            actual = urlparse(authority)
            assert actual.scheme == "https"
            assert actual.netloc == expected_netloc

    transport = Mock(send=Mock(side_effect=Exception("credential shouldn't send a request")))
    MockCredential(_cache=TokenCache(), authority=authority, transport=transport)

    with patch.dict("os.environ", {EnvironmentVariables.AZURE_AUTHORITY_HOST: authority}, clear=True):
        MockCredential(_cache=TokenCache(), authority=authority, transport=transport)
async def test_empty_cache():
    """the credential should raise CredentialUnavailableError when the cache is empty"""

    with pytest.raises(CredentialUnavailableError, match=NO_ACCOUNTS):
        await SharedTokenCacheCredential(_cache=TokenCache()
                                         ).get_token("scope")
    with pytest.raises(CredentialUnavailableError, match=NO_ACCOUNTS):
        await SharedTokenCacheCredential(
            _cache=TokenCache(), username="******").get_token("scope")
    with pytest.raises(CredentialUnavailableError, match=NO_ACCOUNTS):
        await SharedTokenCacheCredential(
            _cache=TokenCache(), tenant_id="not-cached").get_token("scope")
    with pytest.raises(CredentialUnavailableError, match=NO_ACCOUNTS):
        credential = SharedTokenCacheCredential(_cache=TokenCache(),
                                                tenant_id="not-cached",
                                                username="******")
        await credential.get_token("scope")
Exemplo n.º 18
0
def test_multitenant_cache():
    client_id = "client-id"
    scope = "scope"
    expected_token = "***"
    tenant_a = "tenant-a"
    tenant_b = "tenant-b"
    tenant_c = "tenant-c"
    authority = "https://localhost/" + tenant_a

    cache = TokenCache()
    cache.add({
        "response":
        build_aad_response(access_token=expected_token),
        "client_id":
        client_id,
        "scope": [scope],
        "token_endpoint":
        "/".join((authority, tenant_a, "oauth2/v2.0/token")),
    })

    common_args = dict(authority=authority, cache=cache, client_id=client_id)
    client_a = AadClient(tenant_id=tenant_a, **common_args)
    client_b = AadClient(tenant_id=tenant_b, **common_args)

    # A has a cached token
    token = client_a.get_cached_access_token([scope])
    assert token.token == expected_token

    # which B shouldn't return
    assert client_b.get_cached_access_token([scope]) is None

    # but C allows multitenant auth and should therefore return the token from tenant_a when appropriate
    client_c = AadClient(tenant_id=tenant_c,
                         allow_multitenant_authentication=True,
                         **common_args)
    assert client_c.get_cached_access_token([scope]) is None
    token = client_c.get_cached_access_token([scope], tenant_id=tenant_a)
    assert token.token == expected_token
    with patch.dict("os.environ", {
            EnvironmentVariables.AZURE_IDENTITY_ENABLE_LEGACY_TENANT_SELECTION:
            "true"
    },
                    clear=True):
        assert client_c.get_cached_access_token([scope],
                                                tenant_id=tenant_a) is None
Exemplo n.º 19
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
Exemplo n.º 20
0
 def __init__(
     self, client_id="...", request_token=None, cache=None, msal_app_factory=None, transport=None, **kwargs
 ):
     self._msal_app_factory = msal_app_factory
     self._request_token_impl = request_token or Mock()
     transport = transport or Mock(send=Mock(side_effect=Exception("credential shouldn't send a request")))
     super(MockCredential, self).__init__(
         client_id=client_id, _cache=cache or TokenCache(), transport=transport, **kwargs
     )
Exemplo n.º 21
0
def test_disable_automatic_authentication():
    """When configured for strict silent auth, the credential should raise when silent auth fails"""

    empty_cache = TokenCache()  # empty cache makes silent auth impossible
    transport = Mock(send=Mock(side_effect=Exception("no request should be sent")))
    credential = DeviceCodeCredential("client-id", disable_automatic_authentication=True, transport=transport, _cache=empty_cache)

    with pytest.raises(AuthenticationRequiredError):
        credential.get_token("scope")
async def test_evicts_invalid_refresh_token():
    """when AAD rejects a refresh token, the client should evict that token from its cache"""

    tenant_id = "tenant-id"
    client_id = "client-id"
    invalid_token = "invalid-refresh-token"

    cache = TokenCache()
    cache.add({
        "response":
        build_aad_response(uid="id1",
                           utid="tid1",
                           access_token="*",
                           refresh_token=invalid_token)
    })
    cache.add({
        "response":
        build_aad_response(uid="id2",
                           utid="tid2",
                           access_token="*",
                           refresh_token="...")
    })
    assert len(cache.find(TokenCache.CredentialType.REFRESH_TOKEN)) == 2
    assert len(
        cache.find(TokenCache.CredentialType.REFRESH_TOKEN,
                   query={"secret": invalid_token})) == 1

    async def send(request, **_):
        assert request.data["refresh_token"] == invalid_token
        return mock_response(json_payload={"error": "invalid_grant"},
                             status_code=400)

    transport = Mock(send=Mock(wraps=send))

    client = AadClient(tenant_id, client_id, transport=transport, cache=cache)
    with pytest.raises(ClientAuthenticationError):
        await client.obtain_token_by_refresh_token(scopes=("scope", ),
                                                   refresh_token=invalid_token)

    assert transport.send.call_count == 1
    assert len(cache.find(TokenCache.CredentialType.REFRESH_TOKEN)) == 1
    assert len(
        cache.find(TokenCache.CredentialType.REFRESH_TOKEN,
                   query={"secret": invalid_token})) == 0
Exemplo n.º 23
0
def test_authentication_record_empty_cache():
    record = AuthenticationRecord("tenant_id", "client_id", "authority",
                                  "home_account_id", "username")
    transport = Mock(
        side_effect=Exception("the credential shouldn't send a request"))
    credential = SharedTokenCacheCredential(authentication_record=record,
                                            transport=transport,
                                            _cache=TokenCache())

    with pytest.raises(CredentialUnavailableError):
        credential.get_token("scope")
 def __init__(self, request_factory, client_id=None, resource_id=None, identity_config=None, **kwargs):
     # type: (Callable[[str, dict], HttpRequest], Optional[str], Optional[str], Optional[Dict], **Any) -> None
     self._cache = kwargs.pop("_cache", None) or TokenCache()
     self._content_callback = kwargs.pop("_content_callback", None)
     self._identity_config = identity_config or {}
     if client_id:
         self._identity_config["client_id"] = client_id
     if resource_id:
         self._identity_config["mi_res_id"] = resource_id
     self._pipeline = self._build_pipeline(**kwargs)
     self._request_factory = request_factory
    def __init__(
        self, tenant_id, client_id, authority=None, cache=None, **kwargs
    ):
        # type: (str, str, Optional[str], Optional[TokenCache], **Any) -> None
        self._authority = normalize_authority(authority) if authority else get_default_authority()

        self._tenant_id = tenant_id

        self._cache = cache or TokenCache()
        self._client_id = client_id
        self._pipeline = self._build_pipeline(**kwargs)
Exemplo n.º 26
0
def test_close():
    transport = MagicMock()
    credential = SharedTokenCacheCredential(transport=transport, _cache=TokenCache())
    with pytest.raises(CredentialUnavailableError):
        credential.get_token('scope')

    assert not transport.__enter__.called
    assert not transport.__exit__.called

    credential.close()
    assert not transport.__enter__.called
    assert transport.__exit__.call_count == 1
def test_disable_automatic_authentication():
    """When configured for strict silent auth, the credential should raise when silent auth fails"""

    empty_cache = TokenCache()  # empty cache makes silent auth impossible
    transport = Mock(send=Mock(side_effect=Exception("no request should be sent")))
    credential = InteractiveBrowserCredential(
        _disable_automatic_authentication=True, transport=transport, _cache=empty_cache
    )

    with patch(WEBBROWSER_OPEN, Mock(side_effect=Exception("credential shouldn't try interactive authentication"))):
        with pytest.raises(AuthenticationRequiredError):
            credential.get_token("scope")
Exemplo n.º 28
0
def test_access_token_caching():
    """'get_token' shouldn't return other users' access tokens"""

    scope = "scope"
    forbidden_access_token = "don't use me"
    expected_access_token = "access token"
    my_refresh_token = "my refresh token"
    your_refresh_token = "your refresh token"

    me = "me"
    uid = "uidme"
    utid = "utidme"
    cache = TokenCache()
    cache.add(
        get_account_event(
            username=me,
            uid=uid,
            utid=utid,
            refresh_token=my_refresh_token,
            access_token=forbidden_access_token,
            scopes=[scope],
        ))

    you = "you"
    uid = "uidyou"
    utid = "utidyou"
    cache.add(
        get_account_event(
            username=you,
            uid=uid,
            utid=utid,
            refresh_token=your_refresh_token,
            access_token=expected_access_token,
            scopes=[scope],
        ))
Exemplo n.º 29
0
    def __init__(self, tenant_id, client_id, cache=None, **kwargs):
        # type: (str, str, **Any) -> None
        authority = kwargs.pop("authority", KnownAuthorities.AZURE_PUBLIC_CLOUD)
        if authority[-1] == "/":
            authority = authority[:-1]
        token_endpoint = "https://" + "/".join((authority, tenant_id, "oauth2/v2.0/token"))
        config = {"token_endpoint": token_endpoint}

        self._cache = cache or TokenCache()

        self._client = Client(server_configuration=config, client_id=client_id)
        self._client.session.close()
        self._client.session = self._get_client_session(**kwargs)
Exemplo n.º 30
0
    def __init__(self, tenant_id, client_id, cache=None, **kwargs):
        # type: (str, str, Optional[TokenCache], **Any) -> None
        authority = kwargs.pop("authority", None)
        authority = normalize_authority(authority) if authority else get_default_authority()

        token_endpoint = "/".join((authority, tenant_id, "oauth2/v2.0/token"))
        config = {"token_endpoint": token_endpoint}

        self._cache = cache or TokenCache()

        self._client = Client(server_configuration=config, client_id=client_id)
        self._client.session.close()
        self._client.session = self._get_client_session(**kwargs)