Skip to content

Commit 4defbc7

Browse files
authored
aci returns non-json response for probing request (#36193)
* aci returns non-json response for probing request * update * update release date
1 parent 6632e13 commit 4defbc7

File tree

5 files changed

+84
-13
lines changed

5 files changed

+84
-13
lines changed

sdk/identity/azure-identity/CHANGELOG.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
# Release History
22

3-
## 1.17.1 (Unreleased)
4-
5-
### Features Added
6-
7-
### Breaking Changes
3+
## 1.17.1 (2024-06-21)
84

95
### Bugs Fixed
106

11-
### Other Changes
7+
- Continue to attempt requesting token if the probing request receives non-json response. ([#36184](https://github.com/Azure/azure-sdk-for-python/pull/36184))
128

139
## 1.17.0 (2024-06-18)
1410

sdk/identity/azure-identity/azure/identity/_credentials/imds.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,6 @@ def _request_token(self, *scopes: str, **kwargs: Any) -> AccessToken:
8787
try:
8888
self._client.request_token(*scopes, connection_timeout=1, retry_total=0)
8989
self._endpoint_available = True
90-
except CredentialUnavailableError:
91-
# Response is not json, skip the IMDS credential
92-
raise
9390
except HttpResponseError as ex:
9491
# IMDS responded
9592
_check_forbidden_response(ex)
@@ -102,6 +99,9 @@ def _request_token(self, *scopes: str, **kwargs: Any) -> AccessToken:
10299

103100
try:
104101
token = self._client.request_token(*scopes, headers={"Metadata": "true"})
102+
except CredentialUnavailableError:
103+
# Response is not json, skip the IMDS credential
104+
raise
105105
except HttpResponseError as ex:
106106
# 400 in response to a token request indicates managed identity is disabled,
107107
# or the identity with the specified client_id is not available

sdk/identity/azure-identity/azure/identity/aio/_credentials/imds.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@ async def _request_token(self, *scopes: str, **kwargs: Any) -> AccessToken: # p
4545
try:
4646
await self._client.request_token(*scopes, connection_timeout=1, retry_total=0)
4747
self._endpoint_available = True
48-
except CredentialUnavailableError:
49-
# Response is not json, skip the IMDS credential
50-
raise
5148
except HttpResponseError as ex:
5249
# IMDS responded
5350
_check_forbidden_response(ex)
@@ -60,6 +57,9 @@ async def _request_token(self, *scopes: str, **kwargs: Any) -> AccessToken: # p
6057

6158
try:
6259
token = await self._client.request_token(*scopes, headers={"Metadata": "true"})
60+
except CredentialUnavailableError:
61+
# Response is not json, skip the IMDS credential
62+
raise
6363
except HttpResponseError as ex:
6464
# 400 in response to a token request indicates managed identity is disabled,
6565
# or the identity with the specified client_id is not available

sdk/identity/azure-identity/tests/test_imds_credential.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def test_retries():
9393

9494
total_retries = PIPELINE_SETTINGS["retry_total"]
9595

96-
assert within_credential_chain.get() == False
96+
assert not within_credential_chain.get()
9797
for status_code in (404, 410, 429, 500):
9898
mock_send.reset_mock()
9999
mock_response.status_code = status_code
@@ -251,3 +251,40 @@ def test_user_assigned_tenant_id(self):
251251
token = credential.get_token(self.scope, tenant_id="tenant_id")
252252
assert token.token
253253
assert isinstance(token.expires_on, int)
254+
255+
def test_managed_identity_aci_probe(self):
256+
access_token = "****"
257+
expires_on = 42
258+
expected_token = AccessToken(access_token, expires_on)
259+
scope = "scope"
260+
transport = validating_transport(
261+
requests=[
262+
Request(base_url=IMDS_AUTHORITY + IMDS_TOKEN_PATH),
263+
Request(
264+
base_url=IMDS_AUTHORITY + IMDS_TOKEN_PATH,
265+
method="GET",
266+
required_headers={"Metadata": "true"},
267+
required_params={"resource": scope},
268+
),
269+
],
270+
responses=[
271+
# probe receives error response
272+
mock_response(status_code=400),
273+
mock_response(
274+
json_payload={
275+
"access_token": access_token,
276+
"expires_in": 42,
277+
"expires_on": expires_on,
278+
"ext_expires_in": 42,
279+
"not_before": int(time.time()),
280+
"resource": scope,
281+
"token_type": "Bearer",
282+
}
283+
),
284+
],
285+
)
286+
within_credential_chain.set(True)
287+
cred = ImdsCredential(transport=transport)
288+
token = cred.get_token(scope)
289+
assert token == expected_token
290+
within_credential_chain.set(False)

sdk/identity/azure-identity/tests/test_imds_credential_async.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from azure.identity._credentials.imds import IMDS_AUTHORITY, IMDS_TOKEN_PATH
1515
from azure.identity._internal.user_agent import USER_AGENT
1616
from azure.identity.aio._credentials.imds import ImdsCredential, PIPELINE_SETTINGS
17+
from azure.identity._internal.utils import within_credential_chain
1718
import pytest
1819

1920
from helpers import mock_response, Request
@@ -291,3 +292,40 @@ async def test_user_assigned_tenant_id(self):
291292
token = await credential.get_token(self.scope, tenant_id="tenant_id")
292293
assert token.token
293294
assert isinstance(token.expires_on, int)
295+
296+
@pytest.mark.asyncio
297+
async def test_managed_identity_aci_probe(self):
298+
access_token = "****"
299+
expires_on = 42
300+
expected_token = AccessToken(access_token, expires_on)
301+
scope = "scope"
302+
transport = async_validating_transport(
303+
requests=[
304+
Request(base_url=IMDS_AUTHORITY + IMDS_TOKEN_PATH),
305+
Request(
306+
base_url=IMDS_AUTHORITY + IMDS_TOKEN_PATH,
307+
method="GET",
308+
required_headers={"Metadata": "true"},
309+
required_params={"resource": scope},
310+
),
311+
],
312+
responses=[
313+
mock_response(status_code=400),
314+
mock_response(
315+
json_payload={
316+
"access_token": access_token,
317+
"expires_in": 42,
318+
"expires_on": expires_on,
319+
"ext_expires_in": 42,
320+
"not_before": int(time.time()),
321+
"resource": scope,
322+
"token_type": "Bearer",
323+
}
324+
),
325+
],
326+
)
327+
within_credential_chain.set(True)
328+
cred = ImdsCredential(transport=transport)
329+
token = await cred.get_token(scope)
330+
assert token == expected_token
331+
within_credential_chain.set(False)

0 commit comments

Comments
 (0)