You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Docs] Add SupportsTokenInfo details to dev guide (#39931)
Added some details about the newer `SupportsTokenInfo` protocols into
the CLIENT_LIBRARY_DEVELOPER.md file.
Signed-off-by: Paul Van Eck <[email protected]>
The Azure Core pipeline is a re-structuring of the msrest pipeline introduced in msrest 0.6.0.
@@ -544,10 +565,67 @@ class Pipeline:
544
565
545
566
## Credentials
546
567
547
-
### TokenCredential protocol
568
+
### Token Credential Protocols
569
+
570
+
Clients from the Azure SDK often require a credential instance in their constructors. Azure Core offers several protocols for credential types that provide OAuth tokens. The main protocols are `SupportsTokenInfo` (preferred) and `TokenCredential` (legacy).
571
+
572
+
#### SupportsTokenInfo and AsyncSupportsTokenInfo protocols (preferred)
573
+
574
+
These protocols are the preferred way to implement new credential types in the Azure SDK. They are capable of providing enhanced token information and also provide a more structured approach to token requests compared to the legacy `TokenCredential` protocol. New credential implementations should aim to implement these protocols.
575
+
576
+
The `SupportsTokenInfo` protocol specifies a class that implements `get_token_info` which returns an `AccessTokenInfo` object which contains the token string, its expiration time, and additional properties such as `refresh_on` and `token_type`.
577
+
578
+
```python
579
+
classAccessTokenInfo:
580
+
"""Information about an OAuth access token.
581
+
582
+
This class is an alternative to `AccessToken` which provides additional
583
+
information about the token.
584
+
"""
585
+
586
+
token: str
587
+
"""The token string."""
588
+
expires_on: int
589
+
"""The token's expiration time in Unix time."""
590
+
token_type: str
591
+
"""The type of access token."""
592
+
refresh_on: Optional[int]
593
+
"""Specifies the time, in Unix time, when the cached token should be proactively
:keyword options: A dictionary of options for the token request. Unknown options will be ignored.
605
+
:paramtype options: TokenRequestOptions
606
+
607
+
:rtype: AccessTokenInfo
608
+
:return: An AccessTokenInfo instance containing information about the token.
609
+
"""
610
+
611
+
defclose(self) -> None:
612
+
...
613
+
```
614
+
615
+
The async version `AsyncSupportsTokenInfo` provides the same functionality but with async/await support and requires implementation of the async context manager protocol (`__aenter__`, `__aexit__`, and `close` methods should be implemented).
616
+
617
+
The `get_token_info` methods use `TokenRequestOptions` to handle token request parameters in a more structured way:
618
+
619
+
```python
620
+
classTokenRequestOptions(TypedDict, total=False):
621
+
claims: str# Additional claims required in the token
622
+
tenant_id: str# The tenant ID for the token request
623
+
enable_cae: bool# Whether to enable Continuous Access Evaluation
624
+
```
625
+
626
+
#### TokenCredential protocol (legacy)
548
627
549
-
Clients from the Azure SDK often require a `TokenCredential` instance in their constructors. A `TokenCredential` is
550
-
meant to provide OAuth tokens to authenticate service requests and can be implemented in a number of ways.
628
+
While still supported, the `TokenCredential` protocol is considered legacy as it has extensibility limitations. It is recommended to use `SupportsTokenInfo` for new credential implementations. Generally, to ensure compatibility with existing clients, new credential implementations should implement both `SupportsTokenInfo` and `TokenCredential`.
551
629
552
630
The `TokenCredential` protocol specifies a class that has a single method -- `get_token` -- which returns an
553
631
`AccessToken`: a `NamedTuple` containing a `token` string and an `expires_on` integer (in Unix time).
@@ -559,7 +637,12 @@ class TokenCredential(Protocol):
559
637
"""Protocol for classes able to provide OAuth tokens."""
@@ -576,22 +659,56 @@ class TokenCredential(Protocol):
576
659
"""
577
660
```
578
661
579
-
A `TokenCredential` implementation needs to implement the `get_token` method to these specifications and can optionally
580
-
implement additional methods. The [`azure-identity`][identity_github] package has a number of `TokenCredential`
581
-
implementations that can be used for reference. For example, the [`InteractiveCredential`][interactive_cred] is used as
582
-
a base class for multiple credentials and uses `claims` and `tenant_id` in token requests.
662
+
The async version `AsyncTokenCredential` provides the same functionality but with async/await support and also requires implementation of the async context manager protocol (`__aenter__`, `__aexit__`, and `close` methods should be implemented).
663
+
664
+
If a `TokenCredential` implementation doesn't have a use for a keyword argument in a given scenario, the documentation for the implementation should mention that this keyword argument will not be used when making token requests, as well as any potential consequences of this. For example, if a `TokenCredential` implementation doesn't use `tenant_id`, it should document that fetched tokens may not authorize requests made to the specified tenant.
665
+
666
+
When implementing the `get_token` method, ensure all keyword arguments are explicitly defined rather than using `**kwargs`. This approach prevents unintended keyword arguments from being passed to the HTTP transport layer, which could lead to unexpected behavior. The `get_token_info` method in `SupportsTokenInfo` does not have this issue, as it uses a `TokenRequestOptions` object to handle token request parameters.
667
+
668
+
### Implementation Guidance
583
669
584
-
If a `TokenCredential` implementation doesn't have a use for a keyword argument in a given scenario, the unused
585
-
keyword argument should be removed from `kwargs` before getting passed elsewhere. The documentation for the
586
-
implementation should mention that this keyword argument will not be used when making token requests, as well as any
587
-
potential consequences of this. For example, if a `TokenCredential` implementation doesn't use `tenant_id`, it should
588
-
document that fetched tokens may not authorize requests made to the specified tenant.
670
+
When implementing a new credential type:
671
+
672
+
1. Implement `SupportsTokenInfo`/`AsyncSupportsTokenInfo` as your primary protocol
673
+
2. If backwards compatibility is needed:
674
+
- Implement `TokenCredential`/`AsyncTokenCredential` as a secondary protocol
675
+
- Convert `get_token_info` results to `AccessToken` in the `get_token` implementation
676
+
677
+
Example structure for a new credential implementation:
678
+
679
+
```python
680
+
from azure.core.credentials import AccessToken, AccessTokenInfo, TokenRequestOptions
There is also an async protocol -- the `AsyncTokenCredential` protocol -- that specifies a class with an async
591
-
`get_token` method with the same arguments. An `AsyncTokenCredential` implementation additionally needs to be a context
592
-
manager, with `__aenter__`, `__aexit__`, and `close` methods.
709
+
The [`azure-identity`][identity_github] package has a number of credentials that implement both protocols, and serves as a good reference for implementing new credentials. For example, the [`InteractiveCredential`][interactive_cred] is used as a base class for multiple credentials and uses `claims` and `tenant_id` in token requests.
593
710
594
-
####Known uses of `get_token` keyword-only parameters
711
+
### Known uses of token request parameters
595
712
596
713
**`claims`**
597
714
@@ -613,9 +730,9 @@ manager, with `__aenter__`, `__aexit__`, and `close` methods.
613
730
614
731
### BearerTokenCredentialPolicy and AsyncBearerTokenCredentialPolicy
615
732
616
-
`BearerTokenCredentialPolicy` and `AsyncBearerTokenCredentialPolicy` are HTTP policies that are used to authenticate requests to services that accept bearer tokens in their authorization headers. These credential policies take a `TokenCredential`instance and scopes as parameters in their constructors. The `TokenCredential` instance is used to get an access token for the scopes, and the policy adds the token to the request's authorization header.
733
+
`BearerTokenCredentialPolicy` and `AsyncBearerTokenCredentialPolicy` are HTTP policies that are used to authenticate requests to services that accept bearer tokens in their authorization headers. These credential policies take `SupportsTokenInfo`/`TokenCredential`instances and scopes as parameters in their constructors. The `SupportsTokenInfo`/`TokenCredential` instance is used to get an access token for the scopes, and the policy adds the token to the request's authorization header.
617
734
618
-
Both of these policies also accept an `enable_cae` keyword argument that is passed to the `TokenCredential` instance's `get_token` method if set to `True`. This argument is used to indicate that the requested token should be [CAE-enabled][cae_doc]. If an SDK's service supports CAE, it should set this value to `True` when creating the policy.
735
+
Both of these policies also accept an `enable_cae` keyword argument that is passed to the `SupportsTokenInfo`/`TokenCredential` instance's `get_token_info`/`get_token` method if set to `True`. This argument is used to indicate that the requested token should be [CAE-enabled][cae_doc]. If an SDK's service supports CAE, it should set this value to `True` when creating the policy.
619
736
620
737
```python
621
738
from azure.core.pipeline.policies import BearerTokenCredentialPolicy
0 commit comments