-
Notifications
You must be signed in to change notification settings - Fork 142
Add extensibility documentation for access token management #912
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
cf18b1e
Add extensibility documentation for access token management
maartenba 00386dd
Enhance extensibility documentation for token retrieval
Erwinvandervalk 8572a95
Apply suggestion from @maartenba
maartenba 2a32186
Apply suggestion from @maartenba
maartenba 0537dc8
Apply suggestion from @maartenba
maartenba f5d5a3f
Apply suggestion from @maartenba
maartenba 3d47c18
Apply suggestion from @maartenba
maartenba File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
98 changes: 98 additions & 0 deletions
98
src/content/docs/accesstokenmanagement/advanced/extensibility.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| --- | ||
| title: Extensibility | ||
| description: Learn how to extend and customize Duende.AccessTokenManagement, including custom token retrieval. | ||
| sidebar: | ||
| label: Extensibility | ||
| order: 50 | ||
| --- | ||
|
|
||
| There are several extension points where you can customize the behavior of Duende.AccessTokenManagement. | ||
| The extension model is designed to favor composition over inheritance, making it easier to customize and extend while maintaining the library's core functionality. | ||
|
|
||
| ## Token Retrieval | ||
|
|
||
| Token retrieval can be customized by implementing the `AccessTokenRequestHandler.ITokenRetriever` interface. | ||
| This interface defines a single method, `GetTokenAsync`, which is called by the `AccessTokenRequestHandler` to retrieve an access token. | ||
|
|
||
| A common scenario for this would be if you wanted to implement a different token retrieval flow, that's currently not implemented, such as [Impersonation or Delegation grants (RFC 8693)](https://datatracker.ietf.org/doc/html/rfc8693). Implementing this particular flow is outside the scope of this document. | ||
|
|
||
| The following snippet demonstrates how to implement fictive scenario where a custom token retriever dynamically determines which credential flow to use. | ||
|
|
||
| ```csharp | ||
| // CustomTokenRetriever.cs | ||
| public class CustomTokenRetriever( | ||
| UserTokenRequestParameters parameters, | ||
| IClientCredentialsTokenManager clientCredentialsTokenManager, | ||
| IUserTokenManager userTokenManagement, | ||
| IUserAccessor userAccessor, | ||
| ClientCredentialsClientName clientName) : AccessTokenRequestHandler.ITokenRetriever | ||
| { | ||
| public async Task<TokenResult<AccessTokenRequestHandler.IToken>> GetTokenAsync( | ||
| HttpRequestMessage request, CancellationToken ct) | ||
| { | ||
| // You'll have to make a decision on what token parameters to use, | ||
| // and you can override the default parameters. | ||
| var param = parameters with | ||
| { | ||
| Scope = Scope.Parse("some scope"), | ||
| ForceTokenRenewal = request.GetForceRenewal() // for retry policies. | ||
| }; | ||
|
|
||
| AccessTokenRequestHandler.IToken token; | ||
|
|
||
| // Get the type from current context. | ||
| // Using a random number as an example here. | ||
| int tokenType = new Random().Next(1, 2); | ||
|
|
||
| if (tokenType == 1) | ||
| { | ||
| var getTokenResult = await clientCredentialsTokenManager | ||
| .GetAccessTokenAsync(clientName, param, ct); | ||
|
|
||
| if (!getTokenResult.Succeeded) | ||
| { | ||
| return getTokenResult.FailedResult; | ||
| } | ||
|
|
||
| token = getTokenResult.Token; | ||
| } | ||
| else | ||
| { | ||
| var user = await userAccessor.GetCurrentUserAsync(ct); | ||
|
|
||
| var getTokenResult = await userTokenManagement | ||
| .GetAccessTokenAsync(user, param, ct); | ||
|
|
||
| if (!getTokenResult.Succeeded) | ||
| { | ||
| return getTokenResult.FailedResult; | ||
| } | ||
|
|
||
| token = getTokenResult.Token; | ||
| } | ||
|
|
||
| return TokenResult.Success(token); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| A custom token handler can be linked to your `HttpClient` by creating an `AccessTokenRequestHandler` and adding it to the request pipeline: | ||
|
|
||
| ```csharp | ||
| // Program.cs | ||
| services.AddHttpClient<YourTypedHttpClient>() | ||
maartenba marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| .AddDefaultAccessTokenResiliency() | ||
| .AddHttpMessageHandler(provider => | ||
| { | ||
| var yourCustomTokenRetriever = new CustomTokenRetriever(); | ||
|
|
||
| var logger = provider.GetRequiredService<ILogger<AccessTokenRequestHandler>>(); | ||
| var dPoPProofService = provider.GetRequiredService<IDPoPProofService>(); | ||
| var dPoPNonceStore = provider.GetRequiredService<IDPoPNonceStore>(); | ||
| var accessTokenHandler = new AccessTokenRequestHandler( | ||
| tokenRetriever: yourCustomTokenRetriever, | ||
| dPoPNonceStore: dPoPNonceStore, | ||
| dPoPProofService: dPoPProofService, | ||
| logger: logger); | ||
| }); | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.