diff --git a/README.md b/README.md index 6fb9118..3f2eb6d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ -Integrating [Auth0.NET](https://github.com/auth0/auth0.net) into your project whilst attempting to follow idiomatic .NET Core conventions can be cumbersome and involve a sizable amount of boilerplate shared between projects. +Integrating [Auth0.NET](https://github.com/auth0/auth0.net) into your project whilst following idiomatic .NET conventions can be cumbersome and involve a sizable amount of boilerplate shared between projects. This library hopes to solve that problem, featuring: @@ -18,7 +18,7 @@ This library hopes to solve that problem, featuring: :white_check_mark: `IHttpClientBuilder` extensions, providing handlers to automatically append access tokens to outgoing requests. - This library supports .NET 6 & .NET 7, and is suitable for use in ASP.NET Core and standalone .NET Generic Host applications. + This library supports .NET 6+, and is suitable for use in ASP.NET Core and standalone .NET Generic Host applications. ## Install diff --git a/build/_build.csproj b/build/_build.csproj index 7c541c8..22a941b 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -11,7 +11,7 @@ - + diff --git a/samples/Sample.AspNetCore/Sample.AspNetCore.csproj b/samples/Sample.AspNetCore/Sample.AspNetCore.csproj index b56897c..0448d56 100644 --- a/samples/Sample.AspNetCore/Sample.AspNetCore.csproj +++ b/samples/Sample.AspNetCore/Sample.AspNetCore.csproj @@ -1,15 +1,15 @@  - net7.0 + net8.0 ed89c14f-ea75-4b37-83e7-078870067ffc enable enable - - + + diff --git a/samples/Sample.ConsoleApp/Sample.ConsoleApp.csproj b/samples/Sample.ConsoleApp/Sample.ConsoleApp.csproj index 342a1d1..947acd9 100644 --- a/samples/Sample.ConsoleApp/Sample.ConsoleApp.csproj +++ b/samples/Sample.ConsoleApp/Sample.ConsoleApp.csproj @@ -2,20 +2,20 @@ Exe - net7.0 + net8.0 enable enable 096fd757-814d-4d2a-a02e-ef4f19cdc656 - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/src/Auth0Net.DependencyInjection/Auth0Extensions.cs b/src/Auth0Net.DependencyInjection/Auth0Extensions.cs index 315f33d..548825c 100644 --- a/src/Auth0Net.DependencyInjection/Auth0Extensions.cs +++ b/src/Auth0Net.DependencyInjection/Auth0Extensions.cs @@ -32,14 +32,7 @@ public static IHttpClientBuilder AddAuth0AuthenticationClientCore(this IServiceC .Configure(x => x.Domain = domain) .Validate(x => !string.IsNullOrWhiteSpace(x.Domain), "Auth0 Domain cannot be null or empty"); - services.AddSingleton(); - return services.AddHttpClient() - .ConfigurePrimaryHttpMessageHandler(() => - new SocketsHttpHandler() - { - PooledConnectionLifetime = TimeSpan.FromMinutes(2) - }) - .SetHandlerLifetime(Timeout.InfiniteTimeSpan); + return services.AddAuth0AuthenticationClientInternal(); } /// @@ -60,10 +53,41 @@ public static IHttpClientBuilder AddAuth0AuthenticationClient(this IServiceColle .Configure(config) .Validate(x => !string.IsNullOrWhiteSpace(x.ClientId) && !string.IsNullOrWhiteSpace(x.Domain) && !string.IsNullOrWhiteSpace(x.ClientSecret), "Auth0 Configuration cannot have empty values"); + + return services.AddAuth0AuthenticationClientInternal(true); + } + + + /// + /// Adds a integrated with as well as the and related services to the . + /// + /// + /// This configuration is required to use the and token caching integration. + /// + /// The . + /// A delegate that is used to configure the instance of , with the ability to request services from the + /// An that can be used to configure the . + public static IHttpClientBuilder AddAuth0AuthenticationClient(this IServiceCollection services, Action config) + { + if(services.Any(x=> x.ServiceType == typeof(IAuthenticationApiClient))) + throw new InvalidOperationException("AuthenticationApiClient has already been registered!"); - services.AddFusionCache(Constants.FusionCacheInstance); + services.AddOptions() + .Configure(config) + .Validate(x => !string.IsNullOrWhiteSpace(x.ClientId) && !string.IsNullOrWhiteSpace(x.Domain) && !string.IsNullOrWhiteSpace(x.ClientSecret), + "Auth0 Configuration cannot have empty values"); + + return services.AddAuth0AuthenticationClientInternal(true); + } - services.AddSingleton(); + private static IHttpClientBuilder AddAuth0AuthenticationClientInternal(this IServiceCollection services, + bool withCache = false) + { + if (withCache) + { + services.AddFusionCache(Constants.FusionCacheInstance); + services.AddSingleton(); + } services.AddSingleton(); return services.AddHttpClient() @@ -74,12 +98,14 @@ public static IHttpClientBuilder AddAuth0AuthenticationClient(this IServiceColle }) .SetHandlerLifetime(Timeout.InfiniteTimeSpan); } + + /// /// Adds a integrated with to the . /// /// - /// The domain used to construct the Management connection is the same as set in . + /// The domain used to construct the Management connection is the same as set in . /// /// The . /// An that can be used to configure the . @@ -118,10 +144,10 @@ public static IHttpClientBuilder AddAccessToken(this IHttpClientBuilder builder, /// Adds a to the that will automatically add a Auth0 Management Access Token token to the Authorization header. /// /// - /// The domain used to resolve the token is the same as set in . + /// The domain used to resolve the token is the same as set in , unless overriden. /// /// The you wish to configure. - /// Additional configuration for the management client. + /// Additional configuration for the management client for custom domain scenarios. /// An that can be used to configure the . public static IHttpClientBuilder AddManagementAccessToken(this IHttpClientBuilder builder, Action? config = null) { diff --git a/src/Auth0Net.DependencyInjection/Auth0Net.DependencyInjection.csproj b/src/Auth0Net.DependencyInjection/Auth0Net.DependencyInjection.csproj index afeee24..007869f 100644 --- a/src/Auth0Net.DependencyInjection/Auth0Net.DependencyInjection.csproj +++ b/src/Auth0Net.DependencyInjection/Auth0Net.DependencyInjection.csproj @@ -1,11 +1,11 @@  - net6.0;net7.0 + net6.0;net7.0;net8.0 true enable enable - 3.0.0 + 3.1.0 Hawxy Dependency Injection, HttpClientFactory & ASP.NET Core extensions for Auth0.NET true @@ -20,10 +20,10 @@ - - + + - + @@ -38,6 +38,12 @@ + + + + + + <_Parameter1>$(MSBuildProjectName).Tests diff --git a/tests/Auth0Net.DependencyInjection.Tests/Auth0Net.DependencyInjection.Tests.csproj b/tests/Auth0Net.DependencyInjection.Tests/Auth0Net.DependencyInjection.Tests.csproj index 292e3f4..9a64cf3 100644 --- a/tests/Auth0Net.DependencyInjection.Tests/Auth0Net.DependencyInjection.Tests.csproj +++ b/tests/Auth0Net.DependencyInjection.Tests/Auth0Net.DependencyInjection.Tests.csproj @@ -1,16 +1,15 @@  - net6.0;net7.0 - + net6.0;net7.0;net8.0 false - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/tests/Auth0Net.DependencyInjection.Tests/ExtensionTests.cs b/tests/Auth0Net.DependencyInjection.Tests/ExtensionTests.cs index e468071..f165e97 100644 --- a/tests/Auth0Net.DependencyInjection.Tests/ExtensionTests.cs +++ b/tests/Auth0Net.DependencyInjection.Tests/ExtensionTests.cs @@ -128,6 +128,35 @@ public void AddAuth0AuthenticationClient_Resolves_AuthenticationClient() Assert.Equal(clientSecret, configuration.Value.ClientSecret); } + public sealed record FakeConfiguration(string Domain, string ClientId, string ClientSecret); + + [Fact] + public void AddAuth0AuthenticationClient_WithServiceCollection_CanBeResolved() + { + var domain = "test.au.auth0.com"; + var clientId = "fake-id"; + var clientSecret = "fake-secret"; + + var services = new ServiceCollection(); + + services.AddSingleton(new FakeConfiguration(domain, clientId, clientSecret)); + + services.AddAuth0AuthenticationClient((x, p) => + { + var config = p.GetRequiredService(); + + x.Domain = config.Domain; + x.ClientId = config.ClientId; + x.ClientSecret = config.ClientSecret; + }); + + var collection = services.BuildServiceProvider(); + + var authenticationClient = collection.GetService(); + Assert.NotNull(authenticationClient); + Assert.IsType(authenticationClient); + } + [Fact] public void AddAccessToken_Rejects_InvalidConfig() {