|
2 | 2 | # All rights reserved. |
3 | 3 | # |
4 | 4 | # This code is licensed under the MIT License. |
| 5 | +import calendar |
| 6 | +import datetime |
5 | 7 | import json |
6 | 8 | import logging |
7 | 9 | import os |
@@ -432,6 +434,29 @@ def _obtain_token(http_client, managed_identity, resource): |
432 | 434 | return _obtain_token_on_azure_vm(http_client, managed_identity, resource) |
433 | 435 |
|
434 | 436 |
|
| 437 | +def _parse_expires_on(raw: str) -> int: |
| 438 | + try: |
| 439 | + return int(raw) # It is typically an epoch time |
| 440 | + except ValueError: |
| 441 | + pass |
| 442 | + try: |
| 443 | + # '2024-10-18T19:51:37.0000000+00:00' was observed in |
| 444 | + # https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/4963 |
| 445 | + # We support format(s) YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]] |
| 446 | + return int(datetime.datetime.fromisoformat(raw).timestamp()) |
| 447 | + except ValueError: |
| 448 | + pass |
| 449 | + for format in ( |
| 450 | + "%m/%d/%Y %H:%M:%S %z", # Derived from https://github.com/Azure/azure-sdk-for-python/blob/azure-identity_1.21.0/sdk/identity/azure-identity/azure/identity/_credentials/azure_ml.py#L52 |
| 451 | + "%m/%d/%Y %I:%M:%S %p %z", # Derived from https://github.com/Azure/azure-sdk-for-python/blob/azure-identity_1.21.0/sdk/identity/azure-identity/azure/identity/_credentials/azure_ml.py#L51 |
| 452 | + ): |
| 453 | + try: |
| 454 | + return calendar.timegm(time.strptime(raw, format)) |
| 455 | + except ValueError: |
| 456 | + pass |
| 457 | + raise ManagedIdentityError(f"Cannot parse expires_on: {raw}") |
| 458 | + |
| 459 | + |
435 | 460 | def _adjust_param(params, managed_identity, types_mapping=None): |
436 | 461 | # Modify the params dict in place |
437 | 462 | id_name = (types_mapping or ManagedIdentity._types_mapping).get( |
@@ -504,7 +529,7 @@ def _obtain_token_on_app_service( |
504 | 529 | if payload.get("access_token") and payload.get("expires_on"): |
505 | 530 | return { # Normalizing the payload into OAuth2 format |
506 | 531 | "access_token": payload["access_token"], |
507 | | - "expires_in": int(payload["expires_on"]) - int(time.time()), |
| 532 | + "expires_in": _parse_expires_on(payload["expires_on"]) - int(time.time()), |
508 | 533 | "resource": payload.get("resource"), |
509 | 534 | "token_type": payload.get("token_type", "Bearer"), |
510 | 535 | } |
@@ -538,7 +563,7 @@ def _obtain_token_on_machine_learning( |
538 | 563 | if payload.get("access_token") and payload.get("expires_on"): |
539 | 564 | return { # Normalizing the payload into OAuth2 format |
540 | 565 | "access_token": payload["access_token"], |
541 | | - "expires_in": int(payload["expires_on"]) - int(time.time()), |
| 566 | + "expires_in": _parse_expires_on(payload["expires_on"]) - int(time.time()), |
542 | 567 | "resource": payload.get("resource"), |
543 | 568 | "token_type": payload.get("token_type", "Bearer"), |
544 | 569 | } |
|
0 commit comments