From 066617c97ab6c989921c91544d524466a8a0a226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20L=C3=B8ken?= Date: Fri, 12 Dec 2025 14:33:08 +0100 Subject: [PATCH 1/2] Add public interface for ClientCredentialsCacheDurationStore --- .../IClientCredentialsCacheDurationStore.cs | 10 ++++++++++ .../Internal/ClientCredentialsCacheDurationStore.cs | 2 +- .../Internal/ClientCredentialsTokenManager.cs | 2 +- .../ServiceCollectionExtensions.cs | 2 +- ...ApiVerificationTests.GetAllPublicTypes.verified.txt | 1 + ...icApiVerificationTests.VerifyPublicApi.verified.txt | 5 +++++ 6 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 access-token-management/src/AccessTokenManagement/IClientCredentialsCacheDurationStore.cs diff --git a/access-token-management/src/AccessTokenManagement/IClientCredentialsCacheDurationStore.cs b/access-token-management/src/AccessTokenManagement/IClientCredentialsCacheDurationStore.cs new file mode 100644 index 000000000..1b957ed15 --- /dev/null +++ b/access-token-management/src/AccessTokenManagement/IClientCredentialsCacheDurationStore.cs @@ -0,0 +1,10 @@ +// Copyright (c) Duende Software. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + +namespace Duende.AccessTokenManagement; + +public interface IClientCredentialsCacheDurationStore +{ + TimeSpan GetExpiration(ClientCredentialsCacheKey cacheKey); + TimeSpan SetExpiration(ClientCredentialsCacheKey cacheKey, DateTimeOffset expiration); +} diff --git a/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsCacheDurationStore.cs b/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsCacheDurationStore.cs index 9f0960f15..068c696a2 100644 --- a/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsCacheDurationStore.cs +++ b/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsCacheDurationStore.cs @@ -11,7 +11,7 @@ namespace Duende.AccessTokenManagement.Internal; /// internal sealed class ClientCredentialsCacheDurationStore( IOptions options, - TimeProvider time) + TimeProvider time) : IClientCredentialsCacheDurationStore { private readonly ClientCredentialsTokenManagementOptions _options = options.Value; private readonly ConcurrentDictionary _cacheDurations = new(); diff --git a/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsTokenManager.cs b/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsTokenManager.cs index 7a0a877ac..dcfc923cd 100644 --- a/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsTokenManager.cs +++ b/access-token-management/src/AccessTokenManagement/Internal/ClientCredentialsTokenManager.cs @@ -17,7 +17,7 @@ internal class ClientCredentialsTokenManager( TimeProvider time, IClientCredentialsTokenEndpoint client, IClientCredentialsCacheKeyGenerator cacheKeyGenerator, - ClientCredentialsCacheDurationStore cacheDurationAutoTuningStore, + IClientCredentialsCacheDurationStore cacheDurationAutoTuningStore, ILogger logger ) : IClientCredentialsTokenManager { diff --git a/access-token-management/src/AccessTokenManagement/ServiceCollectionExtensions.cs b/access-token-management/src/AccessTokenManagement/ServiceCollectionExtensions.cs index ac2c09c27..d6857af00 100644 --- a/access-token-management/src/AccessTokenManagement/ServiceCollectionExtensions.cs +++ b/access-token-management/src/AccessTokenManagement/ServiceCollectionExtensions.cs @@ -41,7 +41,7 @@ public static ClientCredentialsTokenManagementBuilder AddClientCredentialsTokenM this IServiceCollection services) { services.TryAddTransient(); - services.TryAddSingleton(); + services.TryAddSingleton(); services.AddHybridCache(); // Add a default serializer for ClientCredentialsToken diff --git a/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.GetAllPublicTypes.verified.txt b/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.GetAllPublicTypes.verified.txt index fec49dd29..a4ba1edf9 100644 --- a/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.GetAllPublicTypes.verified.txt +++ b/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.GetAllPublicTypes.verified.txt @@ -26,6 +26,7 @@ Duende.AccessTokenManagement.ForceTokenRenewal Duende.AccessTokenManagement.HttpRequestContext Duende.AccessTokenManagement.HybridCacheConstants Duende.AccessTokenManagement.IClientAssertionService +Duende.AccessTokenManagement.IClientCredentialsCacheDurationStore Duende.AccessTokenManagement.IClientCredentialsCacheKeyGenerator Duende.AccessTokenManagement.IClientCredentialsTokenEndpoint Duende.AccessTokenManagement.IClientCredentialsTokenManager diff --git a/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.VerifyPublicApi.verified.txt b/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.VerifyPublicApi.verified.txt index ee596b9d7..19ed96613 100644 --- a/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.VerifyPublicApi.verified.txt +++ b/access-token-management/test/AccessTokenManagement.Tests/PublicApiVerificationTests.VerifyPublicApi.verified.txt @@ -149,6 +149,11 @@ { System.Threading.Tasks.Task GetClientAssertionAsync(Duende.AccessTokenManagement.ClientCredentialsClientName? clientName = default, Duende.AccessTokenManagement.TokenRequestParameters? parameters = null, System.Threading.CancellationToken ct = default); } + public interface IClientCredentialsCacheDurationStore + { + System.TimeSpan GetExpiration(Duende.AccessTokenManagement.ClientCredentialsCacheKey cacheKey); + System.TimeSpan SetExpiration(Duende.AccessTokenManagement.ClientCredentialsCacheKey cacheKey, System.DateTimeOffset expiration); + } public interface IClientCredentialsCacheKeyGenerator { Duende.AccessTokenManagement.ClientCredentialsCacheKey GenerateKey(Duende.AccessTokenManagement.ClientCredentialsClientName clientName, Duende.AccessTokenManagement.TokenRequestParameters? parameters = null); From 60f4c3a964709ab99219fe589915544eb03f619b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20L=C3=B8ken?= Date: Fri, 12 Dec 2025 15:02:49 +0100 Subject: [PATCH 2/2] Update access-token-management/src/AccessTokenManagement/IClientCredentialsCacheDurationStore.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../IClientCredentialsCacheDurationStore.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/access-token-management/src/AccessTokenManagement/IClientCredentialsCacheDurationStore.cs b/access-token-management/src/AccessTokenManagement/IClientCredentialsCacheDurationStore.cs index 1b957ed15..00b5dc117 100644 --- a/access-token-management/src/AccessTokenManagement/IClientCredentialsCacheDurationStore.cs +++ b/access-token-management/src/AccessTokenManagement/IClientCredentialsCacheDurationStore.cs @@ -5,6 +5,22 @@ namespace Duende.AccessTokenManagement; public interface IClientCredentialsCacheDurationStore { + /// + /// Gets the expiration duration for the specified client credentials cache key. + /// + /// The cache key identifying the client credentials. + /// + /// A representing the duration until the cache entry expires. + /// TimeSpan GetExpiration(ClientCredentialsCacheKey cacheKey); + + /// + /// Sets the expiration for the specified client credentials cache key. + /// + /// The cache key identifying the client credentials. + /// The expiration time to set for the cache entry. + /// + /// A representing the duration until the cache entry expires after setting. + /// TimeSpan SetExpiration(ClientCredentialsCacheKey cacheKey, DateTimeOffset expiration); }