Skip to content

Commit 1022b46

Browse files
authored
[Core] Add refresh_on property to AccessToken (#36183)
Signed-off-by: Paul Van Eck <[email protected]>
1 parent 410263e commit 1022b46

File tree

6 files changed

+46
-4
lines changed

6 files changed

+46
-4
lines changed

sdk/core/azure-core/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
# Release History
22

3-
## 1.30.3 (Unreleased)
3+
## 1.31.0 (Unreleased)
44

55
### Features Added
66

7+
- `AccessToken` now has an optional `refresh_on` attribute that can be used to specify when the token should be refreshed. #36183
8+
- `BearerTokenCredentialPolicy` and `AsyncBearerTokenCredentialPolicy` now check the `refresh_on` attribute when determining if a token request should be made.
9+
710
### Breaking Changes
811

912
### Bugs Fixed

sdk/core/azure-core/azure/core/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
# regenerated.
1010
# --------------------------------------------------------------------------
1111

12-
VERSION = "1.30.3"
12+
VERSION = "1.31.0"

sdk/core/azure-core/azure/core/credentials.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ class AccessToken(NamedTuple):
1212

1313
token: str
1414
expires_on: int
15+
refresh_on: Optional[int] = None
1516

1617

1718
AccessToken.token.__doc__ = """The token string."""
1819
AccessToken.expires_on.__doc__ = """The token's expiration time in Unix time."""
20+
AccessToken.refresh_on.__doc__ = """When the token should be refreshed in Unix time."""
1921

2022

2123
@runtime_checkable

sdk/core/azure-core/azure/core/pipeline/policies/_authentication.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,12 @@ def _update_headers(headers: MutableMapping[str, str], token: str) -> None:
6969

7070
@property
7171
def _need_new_token(self) -> bool:
72-
return not self._token or self._token.expires_on - time.time() < 300
72+
now = time.time()
73+
return (
74+
not self._token
75+
or (self._token.refresh_on is not None and self._token.refresh_on <= now)
76+
or self._token.expires_on - now < 300
77+
)
7378

7479

7580
class BearerTokenCredentialPolicy(_BearerTokenCredentialPolicyBase, HTTPPolicy[HTTPRequestType, HTTPResponseType]):

sdk/core/azure-core/azure/core/pipeline/policies/_authentication_async.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,9 @@ def on_exception(self, request: PipelineRequest[HTTPRequestType]) -> None:
164164
return
165165

166166
def _need_new_token(self) -> bool:
167-
return not self._token or self._token.expires_on - time.time() < 300
167+
now = time.time()
168+
return (
169+
not self._token
170+
or (self._token.refresh_on is not None and self._token.refresh_on <= now)
171+
or self._token.expires_on - now < 300
172+
)

sdk/core/azure-core/tests/test_authentication.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,33 @@ def test_key_vault_regression(http_request):
305305
assert policy._token.token == token
306306

307307

308+
def test_need_new_token():
309+
expected_scope = "scope"
310+
now = int(time.time())
311+
312+
policy = BearerTokenCredentialPolicy(Mock(), expected_scope)
313+
314+
# Token is expired.
315+
policy._token = AccessToken("", now - 1200)
316+
assert policy._need_new_token
317+
318+
# Token is about to expire within 300 seconds.
319+
policy._token = AccessToken("", now + 299)
320+
assert policy._need_new_token
321+
322+
# Token still has more than 300 seconds to live.
323+
policy._token = AccessToken("", now + 305)
324+
assert not policy._need_new_token
325+
326+
# Token has both expires_on and refresh_on set well into the future.
327+
policy._token = AccessToken("", now + 1200, now + 1200)
328+
assert not policy._need_new_token
329+
330+
# Token is not close to expiring, but refresh_on is in the past.
331+
policy._token = AccessToken("", now + 1200, now - 1)
332+
assert policy._need_new_token
333+
334+
308335
@pytest.mark.parametrize("http_request", HTTP_REQUESTS)
309336
def test_azure_key_credential_policy(http_request):
310337
"""Tests to see if we can create an AzureKeyCredentialPolicy"""

0 commit comments

Comments
 (0)