Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def __init__(self, **kwargs):

self._credential = TokenExchangeCredential(
tenant_id=os.environ[EnvironmentVariables.AZURE_TENANT_ID],
client_id=os.environ[EnvironmentVariables.AZURE_CLIENT_ID],
client_id=kwargs.pop("client_id", os.environ[EnvironmentVariables.AZURE_CLIENT_ID]),
token_file_path=os.environ[EnvironmentVariables.AZURE_FEDERATED_TOKEN_FILE],
**kwargs
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def __init__(self, **kwargs: "Any") -> None:

self._credential = TokenExchangeCredential(
tenant_id=os.environ[EnvironmentVariables.AZURE_TENANT_ID],
client_id=os.environ[EnvironmentVariables.AZURE_CLIENT_ID],
client_id=kwargs.pop("client_id", os.environ[EnvironmentVariables.AZURE_CLIENT_ID]),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is identity_config consumed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently it's ignored. The platform only accepts "client_id", so really there's no need for identity_config. Of course someone may use it anyway. There are some design considerations to think through before deciding how to handle it. We don't need a solution for this release, so I created #20575.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then should we remove

:keyword identity_config: a mapping ``{parameter_name: value}`` specifying a user-assigned identity by its object
        or resource ID, for example ``{"object_id": "..."}``. Check the documentation for your hosting environment to
        learn what values it expects.
:paramtype identity_config: Mapping[str, str]

from the docstring?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, all other implementations observe it.

token_file_path=os.environ[EnvironmentVariables.AZURE_FEDERATED_TOKEN_FILE],
**kwargs
)
Expand Down
70 changes: 45 additions & 25 deletions sdk/identity/azure-identity/tests/test_managed_identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -790,10 +790,21 @@ def test_token_exchange(tmpdir):
token_file.write(exchange_token)
access_token = "***"
authority = "https://localhost"
client_id = "client_id"
default_client_id = "default_client_id"
tenant = "tenant_id"
scope = "scope"

success_response = mock_response(
json_payload={
"access_token": access_token,
"expires_in": 3600,
"ext_expires_in": 3600,
"expires_on": int(time.time()) + 3600,
"not_before": int(time.time()),
"resource": scope,
"token_type": "Bearer",
}
)
transport = validating_transport(
requests=[
Request(
Expand All @@ -802,38 +813,47 @@ def test_token_exchange(tmpdir):
required_data={
"client_assertion": exchange_token,
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_id": client_id,
"client_id": default_client_id,
"grant_type": "client_credentials",
"scope": scope,
},
)
],
responses=[
mock_response(
json_payload={
"access_token": access_token,
"expires_in": 3600,
"ext_expires_in": 3600,
"expires_on": int(time.time()) + 3600,
"not_before": int(time.time()),
"resource": scope,
"token_type": "Bearer",
}
)
],
responses=[success_response],
)

with mock.patch.dict(
"os.environ",
{
EnvironmentVariables.AZURE_AUTHORITY_HOST: authority,
EnvironmentVariables.AZURE_CLIENT_ID: client_id,
EnvironmentVariables.AZURE_TENANT_ID: tenant,
EnvironmentVariables.AZURE_FEDERATED_TOKEN_FILE: token_file.strpath,
},
clear=True,
):
mock_environ = {
EnvironmentVariables.AZURE_AUTHORITY_HOST: authority,
EnvironmentVariables.AZURE_CLIENT_ID: default_client_id,
EnvironmentVariables.AZURE_TENANT_ID: tenant,
EnvironmentVariables.AZURE_FEDERATED_TOKEN_FILE: token_file.strpath,
}
# credential should default to AZURE_CLIENT_ID
with mock.patch.dict("os.environ", mock_environ, clear=True):
credential = ManagedIdentityCredential(transport=transport)
token = credential.get_token(scope)
assert token.token == access_token

# client_id kwarg should override AZURE_CLIENT_ID
nondefault_client_id = "non" + default_client_id
transport = validating_transport(
requests=[
Request(
base_url=authority,
method="POST",
required_data={
"client_assertion": exchange_token,
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_id": nondefault_client_id,
"grant_type": "client_credentials",
"scope": scope,
},
)
],
responses=[success_response],
)

with mock.patch.dict("os.environ", mock_environ, clear=True):
credential = ManagedIdentityCredential(client_id=nondefault_client_id, transport=transport)
token = credential.get_token(scope)
assert token.token == access_token
70 changes: 45 additions & 25 deletions sdk/identity/azure-identity/tests/test_managed_identity_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -731,10 +731,21 @@ async def test_token_exchange(tmpdir):
token_file.write(exchange_token)
access_token = "***"
authority = "https://localhost"
client_id = "client_id"
default_client_id = "default_client_id"
tenant = "tenant_id"
scope = "scope"

success_response = mock_response(
json_payload={
"access_token": access_token,
"expires_in": 3600,
"ext_expires_in": 3600,
"expires_on": int(time.time()) + 3600,
"not_before": int(time.time()),
"resource": scope,
"token_type": "Bearer",
}
)
transport = async_validating_transport(
requests=[
Request(
Expand All @@ -743,38 +754,47 @@ async def test_token_exchange(tmpdir):
required_data={
"client_assertion": exchange_token,
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_id": client_id,
"client_id": default_client_id,
"grant_type": "client_credentials",
"scope": scope,
},
)
],
responses=[
mock_response(
json_payload={
"access_token": access_token,
"expires_in": 3600,
"ext_expires_in": 3600,
"expires_on": int(time.time()) + 3600,
"not_before": int(time.time()),
"resource": scope,
"token_type": "Bearer",
}
)
],
responses=[success_response],
)

with mock.patch.dict(
"os.environ",
{
EnvironmentVariables.AZURE_AUTHORITY_HOST: authority,
EnvironmentVariables.AZURE_CLIENT_ID: client_id,
EnvironmentVariables.AZURE_TENANT_ID: tenant,
EnvironmentVariables.AZURE_FEDERATED_TOKEN_FILE: token_file.strpath,
},
clear=True,
):
mock_environ = {
EnvironmentVariables.AZURE_AUTHORITY_HOST: authority,
EnvironmentVariables.AZURE_CLIENT_ID: default_client_id,
EnvironmentVariables.AZURE_TENANT_ID: tenant,
EnvironmentVariables.AZURE_FEDERATED_TOKEN_FILE: token_file.strpath,
}
# credential should default to AZURE_CLIENT_ID
with mock.patch.dict("os.environ", mock_environ, clear=True):
credential = ManagedIdentityCredential(transport=transport)
token = await credential.get_token(scope)
assert token.token == access_token

# client_id kwarg should override AZURE_CLIENT_ID
nondefault_client_id = "non" + default_client_id
transport = async_validating_transport(
requests=[
Request(
base_url=authority,
method="POST",
required_data={
"client_assertion": exchange_token,
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_id": nondefault_client_id,
"grant_type": "client_credentials",
"scope": scope,
},
)
],
responses=[success_response],
)

with mock.patch.dict("os.environ", mock_environ, clear=True):
credential = ManagedIdentityCredential(client_id=nondefault_client_id, transport=transport)
token = await credential.get_token(scope)
assert token.token == access_token