< Summary

Information
Class: ArturRios.Util.WebApi.Security.Extensions.AuthenticationServiceCollectionExtensions
Assembly: ArturRios.Util.WebApi
File(s): D:\Repositories\dotnet-webapi-util\src\Security\Extensions\AuthenticationServiceCollectionExtensions.cs
Line coverage
100%
Covered lines: 33
Uncovered lines: 0
Coverable lines: 33
Total lines: 85
Line coverage: 100%
Branch coverage
92%
Covered branches: 13
Total branches: 14
Branch coverage: 92.8%
Method coverage
100%
Covered methods: 2
Fully covered methods: 0
Total methods: 2
Method coverage: 100%
Full method coverage: 0%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
AddCachedAuthenticationProvider(...)100%22100%
AddTokenAuthentication(...)91.66%1212100%

File(s)

D:\Repositories\dotnet-webapi-util\src\Security\Extensions\AuthenticationServiceCollectionExtensions.cs

#LineLine coverage
 1using ArturRios.Util.WebApi.Security.Authentication;
 2using ArturRios.Util.WebApi.Security.Configuration;
 3using ArturRios.Util.WebApi.Security.Interfaces;
 4using ArturRios.Util.WebApi.Security.Providers;
 5using Microsoft.Extensions.Caching.Memory;
 6using Microsoft.Extensions.DependencyInjection;
 7using Microsoft.Extensions.DependencyInjection.Extensions;
 8
 9namespace ArturRios.Util.WebApi.Security.Extensions;
 10
 11/// <summary>
 12/// Dependency-injection helpers for registering authentication providers.
 13/// </summary>
 14public static class AuthenticationServiceCollectionExtensions
 15{
 16    /// <summary>
 17    /// Registers <typeparamref name="TProvider"/> as the underlying <see cref="IAuthenticationProvider"/> and
 18    /// exposes it through a <see cref="CachedAuthenticationProvider"/>, so repeated user lookups within the
 19    /// configured time-to-live are served from an <see cref="IMemoryCache"/> instead of the store.
 20    /// </summary>
 21    /// <typeparam name="TProvider">The concrete provider that performs the actual (e.g. database) lookup.</typeparam>
 22    /// <param name="services">The service collection to register into.</param>
 23    /// <param name="configure">Optional callback to configure caching behavior (time-to-live, negative caching).</param
 24    /// <returns>The same <paramref name="services"/> instance, for chaining.</returns>
 25    public static IServiceCollection AddCachedAuthenticationProvider<TProvider>(
 26        this IServiceCollection services,
 27        Action<CachedAuthenticationProviderOptions>? configure = null)
 28        where TProvider : class, IAuthenticationProvider
 129    {
 130        services.AddMemoryCache();
 131        services.AddScoped<TProvider>();
 32
 133        var options = new CachedAuthenticationProviderOptions();
 134        configure?.Invoke(options);
 35
 136        services.AddScoped<IAuthenticationProvider>(serviceProvider =>
 237            new CachedAuthenticationProvider(
 238                serviceProvider.GetRequiredService<TProvider>(),
 239                serviceProvider.GetRequiredService<IMemoryCache>(),
 240                options));
 41
 142        return services;
 143    }
 44
 45    /// <summary>
 46    /// Registers the consolidated <see cref="AuthenticationOptions"/> and the enabled token validators used by
 47    /// <c>AuthenticationMiddleware</c>. Validators are registered app-JWT first, Google second, so the middleware
 48    /// tries them in that order. The app must separately register <c>JwtConfiguration</c> and <c>JwtHandler</c>
 49    /// (for JWT) and an <see cref="IAuthenticationProvider"/> (required for Google and for JWT <c>Revalidate</c> mode).
 50    /// </summary>
 51    /// <param name="services">The service collection to register into.</param>
 52    /// <param name="configure">Configures the options.</param>
 53    /// <exception cref="ArgumentException">No scheme enabled, or Google enabled without any client IDs.</exception>
 54    public static IServiceCollection AddTokenAuthentication(
 55        this IServiceCollection services, Action<AuthenticationOptions> configure)
 456    {
 457        var options = new AuthenticationOptions();
 458        configure(options);
 59
 460        if (!options.EnableJwt && !options.EnableGoogle)
 161        {
 162            throw new ArgumentException("At least one authentication scheme (JWT or Google) must be enabled.");
 63        }
 64
 365        if (options.EnableGoogle && options.GoogleClientIds.Count == 0)
 166        {
 167            throw new ArgumentException("EnableGoogle requires at least one entry in GoogleClientIds.");
 68        }
 69
 270        services.AddSingleton(options);
 71
 272        if (options.EnableJwt)
 273        {
 274            services.AddSingleton<ITokenValidator, JwtTokenValidator>();
 275        }
 76
 277        if (options.EnableGoogle)
 178        {
 179            services.TryAddSingleton<IGoogleTokenVerifier, GoogleTokenVerifier>();
 180            services.AddSingleton<ITokenValidator, GoogleTokenValidator>();
 181        }
 82
 283        return services;
 284    }
 85}