From d9e35865aaddf0065efad8ed4646ded9b9698c0e Mon Sep 17 00:00:00 2001 From: Brice SCHUMACHER Date: Tue, 28 Oct 2025 21:00:36 +0100 Subject: [PATCH 1/2] refacto: Use a token client instead of calling jwt apis straight --- .../{ => Basic}/BasicAuthBaseClient.cs | 2 +- .../M2M/ClientCredentialsBaseClient.cs | 22 +++++++++++++++++++ .../Authentication/M2M/ITokenClient.cs | 7 ++++++ .../MemoryCachedTokenClient.cs} | 19 ++++------------ .../{ => M2M}/Models/DiscoveryDocument.cs | 2 +- .../{ => M2M}/Models/TokenEndpointResponse.cs | 0 .../TokenClient.cs} | 16 ++++++-------- 7 files changed, 42 insertions(+), 26 deletions(-) rename NotoriousClient/Clients/Authentication/{ => Basic}/BasicAuthBaseClient.cs (96%) create mode 100644 NotoriousClient/Clients/Authentication/M2M/ClientCredentialsBaseClient.cs create mode 100644 NotoriousClient/Clients/Authentication/M2M/ITokenClient.cs rename NotoriousClient/Clients/Authentication/{CachedClientCredentialsBaseClient.cs => M2M/MemoryCachedTokenClient.cs} (67%) rename NotoriousClient/Clients/Authentication/{ => M2M}/Models/DiscoveryDocument.cs (75%) rename NotoriousClient/Clients/Authentication/{ => M2M}/Models/TokenEndpointResponse.cs (100%) rename NotoriousClient/Clients/Authentication/{ClientCredentialsBaseClient.cs => M2M/TokenClient.cs} (69%) diff --git a/NotoriousClient/Clients/Authentication/BasicAuthBaseClient.cs b/NotoriousClient/Clients/Authentication/Basic/BasicAuthBaseClient.cs similarity index 96% rename from NotoriousClient/Clients/Authentication/BasicAuthBaseClient.cs rename to NotoriousClient/Clients/Authentication/Basic/BasicAuthBaseClient.cs index 4ed57fc..5c08d9b 100644 --- a/NotoriousClient/Clients/Authentication/BasicAuthBaseClient.cs +++ b/NotoriousClient/Clients/Authentication/Basic/BasicAuthBaseClient.cs @@ -1,7 +1,7 @@ using NotoriousClient.Builder; using NotoriousClient.Sender; -namespace NotoriousClient.Clients.Authentication +namespace NotoriousClient.Clients.Authentication.BasicAuth { /// /// Base class for HTTP Client preconfigured with Basic Authentication. diff --git a/NotoriousClient/Clients/Authentication/M2M/ClientCredentialsBaseClient.cs b/NotoriousClient/Clients/Authentication/M2M/ClientCredentialsBaseClient.cs new file mode 100644 index 0000000..040a36a --- /dev/null +++ b/NotoriousClient/Clients/Authentication/M2M/ClientCredentialsBaseClient.cs @@ -0,0 +1,22 @@ +using NotoriousClient.Builder; +using NotoriousClient.Sender; + +namespace NotoriousClient.Clients.Authentication.M2M +{ + public abstract class ClientCredentialsBaseClient : BaseClient + { + private readonly ITokenClient _tokenClient; + + public ClientCredentialsBaseClient(ITokenClient tokenClient, IRequestSender sender, string baseUrl) : base(sender, baseUrl) + { + _tokenClient = tokenClient; + } + + protected override async Task GetBuilderAsync(string route, Method method = Method.Get, string? version = null) + { + string token = await _tokenClient.GetAccessToken(); + + return (await base.GetBuilderAsync(route, method, version)).WithAuthentication(token); + } + } +} diff --git a/NotoriousClient/Clients/Authentication/M2M/ITokenClient.cs b/NotoriousClient/Clients/Authentication/M2M/ITokenClient.cs new file mode 100644 index 0000000..bb4e4d9 --- /dev/null +++ b/NotoriousClient/Clients/Authentication/M2M/ITokenClient.cs @@ -0,0 +1,7 @@ +namespace NotoriousClient.Clients.Authentication.M2M +{ + public interface ITokenClient + { + Task GetAccessToken(); + } +} \ No newline at end of file diff --git a/NotoriousClient/Clients/Authentication/CachedClientCredentialsBaseClient.cs b/NotoriousClient/Clients/Authentication/M2M/MemoryCachedTokenClient.cs similarity index 67% rename from NotoriousClient/Clients/Authentication/CachedClientCredentialsBaseClient.cs rename to NotoriousClient/Clients/Authentication/M2M/MemoryCachedTokenClient.cs index b4947d9..367277e 100644 --- a/NotoriousClient/Clients/Authentication/CachedClientCredentialsBaseClient.cs +++ b/NotoriousClient/Clients/Authentication/M2M/MemoryCachedTokenClient.cs @@ -1,33 +1,22 @@ using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; -using NotoriousClient.Builder; -using NotoriousClient.Clients.Authentication.Models; +using NotoriousClient.Clients.Authentication.M2M.Models; using NotoriousClient.Sender; -namespace NotoriousClient.Clients.Authentication +namespace NotoriousClient.Clients.Authentication.M2M { - public class MemoryCachedClientCredentialsBaseClient : ClientCredentialsBaseClient + public class MemoryCachedTokenClient : TokenClient { private const int SKEW_IN_SECONDS = 60; private const int MinimumCacheExpiry = 1; private readonly IMemoryCache _cache; - public MemoryCachedClientCredentialsBaseClient(IRequestSender sender, IMemoryCache cache, IOptions server) : base(sender, server) + public MemoryCachedTokenClient(IRequestSender sender, IMemoryCache cache, IOptions server) : base(sender, server) { _cache = cache ?? throw new ArgumentNullException(nameof(cache)); } - /// - /// Get a preconfigured with Bearer Authentication using ClientCredentials OAuth flow. - /// - protected override async Task GetBuilderAsync(string route, Method method = Method.Get, string? version = null) - { - DiscoveryDocument? discovery = await GetDiscoveryDocument(); - TokenEndpointResponse response = await GetToken(discovery); - - return (await base.GetBuilderAsync(route, method, version)).WithAuthentication(response.AccessToken); - } protected override async Task GetToken(DiscoveryDocument? discovery) diff --git a/NotoriousClient/Clients/Authentication/Models/DiscoveryDocument.cs b/NotoriousClient/Clients/Authentication/M2M/Models/DiscoveryDocument.cs similarity index 75% rename from NotoriousClient/Clients/Authentication/Models/DiscoveryDocument.cs rename to NotoriousClient/Clients/Authentication/M2M/Models/DiscoveryDocument.cs index f1b08d9..39323f1 100644 --- a/NotoriousClient/Clients/Authentication/Models/DiscoveryDocument.cs +++ b/NotoriousClient/Clients/Authentication/M2M/Models/DiscoveryDocument.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace NotoriousClient.Clients.Authentication.Models +namespace NotoriousClient.Clients.Authentication.M2M.Models { public class DiscoveryDocument { diff --git a/NotoriousClient/Clients/Authentication/Models/TokenEndpointResponse.cs b/NotoriousClient/Clients/Authentication/M2M/Models/TokenEndpointResponse.cs similarity index 100% rename from NotoriousClient/Clients/Authentication/Models/TokenEndpointResponse.cs rename to NotoriousClient/Clients/Authentication/M2M/Models/TokenEndpointResponse.cs diff --git a/NotoriousClient/Clients/Authentication/ClientCredentialsBaseClient.cs b/NotoriousClient/Clients/Authentication/M2M/TokenClient.cs similarity index 69% rename from NotoriousClient/Clients/Authentication/ClientCredentialsBaseClient.cs rename to NotoriousClient/Clients/Authentication/M2M/TokenClient.cs index 101ed83..8c05474 100644 --- a/NotoriousClient/Clients/Authentication/ClientCredentialsBaseClient.cs +++ b/NotoriousClient/Clients/Authentication/M2M/TokenClient.cs @@ -1,28 +1,26 @@ using Microsoft.Extensions.Options; using NotoriousClient.Builder; -using NotoriousClient.Clients.Authentication.Models; +using NotoriousClient.Clients.Authentication.M2M.Models; using NotoriousClient.Sender; -namespace NotoriousClient.Clients.Authentication +namespace NotoriousClient.Clients.Authentication.M2M { - public class ClientCredentialsBaseClient : BaseClient + public class TokenClient : BaseClient, ITokenClient { protected IOptions AuthenticationServerOptions { get; private init; } private readonly Endpoint DISCOVERY_ENDPOINT = new Endpoint("/.well-known/openid-configuration", Method.Get); - public ClientCredentialsBaseClient(IRequestSender sender, IOptions server) : base(sender, server.Value.Authority) + public TokenClient(IRequestSender sender, IOptions server) : base(sender, server.Value.Authority) { AuthenticationServerOptions = server ?? throw new ArgumentNullException(nameof(server)); } - protected override async Task GetBuilderAsync(string route, Method method = Method.Get, string? version = null) + public async Task GetAccessToken() { - string tokenEndpoint = string.Empty; - DiscoveryDocument? discovery = await GetDiscoveryDocument(); - TokenEndpointResponse response = await GetToken(discovery); + DiscoveryDocument? discord = await GetDiscoveryDocument(); - return (await base.GetBuilderAsync(route, method, version)).WithAuthentication(response.AccessToken); + return (await GetToken(discord)).AccessToken; } protected virtual async Task GetToken(DiscoveryDocument? discovery) From ff1b1a00894f669b39b2d5788d2e8f1a700d0119 Mon Sep 17 00:00:00 2001 From: Brice SCHUMACHER Date: Tue, 28 Oct 2025 21:06:38 +0100 Subject: [PATCH 2/2] refacto: Use a token client instead of calling jwt apis straight --- .../{ => Authentication/M2M}/AuthorizationServerOptions.cs | 2 +- .../Clients/Authentication/M2M/Models/TokenEndpointResponse.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename NotoriousClient/Clients/{ => Authentication/M2M}/AuthorizationServerOptions.cs (94%) diff --git a/NotoriousClient/Clients/AuthorizationServerOptions.cs b/NotoriousClient/Clients/Authentication/M2M/AuthorizationServerOptions.cs similarity index 94% rename from NotoriousClient/Clients/AuthorizationServerOptions.cs rename to NotoriousClient/Clients/Authentication/M2M/AuthorizationServerOptions.cs index d9be66d..df7b411 100644 --- a/NotoriousClient/Clients/AuthorizationServerOptions.cs +++ b/NotoriousClient/Clients/Authentication/M2M/AuthorizationServerOptions.cs @@ -1,4 +1,4 @@ -namespace NotoriousClient.Clients +namespace NotoriousClient.Clients.Authentication.M2M { public class AuthorizationServerOptions { diff --git a/NotoriousClient/Clients/Authentication/M2M/Models/TokenEndpointResponse.cs b/NotoriousClient/Clients/Authentication/M2M/Models/TokenEndpointResponse.cs index adb04c8..a3b041c 100644 --- a/NotoriousClient/Clients/Authentication/M2M/Models/TokenEndpointResponse.cs +++ b/NotoriousClient/Clients/Authentication/M2M/Models/TokenEndpointResponse.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace NotoriousClient.Clients.Authentication.Models +namespace NotoriousClient.Clients.Authentication.M2M.Models { public class TokenEndpointResponse {