< Summary

Information
Class: Elsa.Identity.Features.DefaultAuthenticationFeature
Assembly: Elsa.Identity
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Identity/Features/DefaultAuthenticationFeature.cs
Line coverage
94%
Covered lines: 34
Uncovered lines: 2
Coverable lines: 36
Total lines: 122
Line coverage: 94.4%
Branch coverage
83%
Covered branches: 5
Total branches: 6
Branch coverage: 83.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_ApiKeyProviderType()100%11100%
get_ConfigureAuthorizationOptions()100%22100%
set_ConfigureAuthorizationOptions(...)100%11100%
UseApiKeyAuthorization()100%22100%
UseAdminApiKey()100%11100%
UseAdminApiKey(...)100%11100%
UseAdminApiKey(...)100%210%
UseDevelopmentAdminApiKey()100%11100%
Apply()50%22100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Identity/Features/DefaultAuthenticationFeature.cs

#LineLine coverage
 1using AspNetCore.Authentication.ApiKey;
 2using Elsa.Extensions;
 3using Elsa.Features.Abstractions;
 4using Elsa.Features.Attributes;
 5using Elsa.Features.Services;
 6using Elsa.Identity.Constants;
 7using Elsa.Identity.Options;
 8using Elsa.Identity.Providers;
 9using Microsoft.AspNetCore.Authentication;
 10using Microsoft.AspNetCore.Authentication.JwtBearer;
 11using Microsoft.AspNetCore.Authorization;
 12using Microsoft.Extensions.DependencyInjection;
 13
 14namespace Elsa.Identity.Features;
 15
 16/// <summary>
 17/// Provides an authorization feature that configures the system with JWT bearer and API key authentication.
 18/// </summary>
 19[DependsOn(typeof(IdentityFeature))]
 20public class DefaultAuthenticationFeature : FeatureBase
 21{
 22    private const string MultiScheme = "Jwt-or-ApiKey";
 623    private Func<AuthenticationBuilder, AuthenticationBuilder> _configureApiKeyAuthorization = builder => builder.AddApi
 24    private Action<AuthorizationOptions>? _configureAuthorizationOptions;
 25
 26    /// <inheritdoc />
 627    public DefaultAuthenticationFeature(IModule module) : base(module)
 28    {
 629    }
 30
 31    /// <summary>
 32    /// Gets or sets the <see cref="ApiKeyProviderType"/>.
 33    /// </summary>
 1234    public Type ApiKeyProviderType { get; set; } = typeof(DefaultApiKeyProvider);
 35
 36    /// <summary>
 37    /// Gets or sets the authorization options configuration.
 38    /// </summary>
 39    /// <remarks>
 40    /// Defaults to a no-op. It previously registered the <c>SecurityRoot</c> policy, which has been retired in
 41    /// favour of endpoint permissions -- see ADR 0010. Hosts that add their own policies keep setting this.
 42    /// </remarks>
 43    public Action<AuthorizationOptions> ConfigureAuthorizationOptions
 44    {
 1145        get => _configureAuthorizationOptions ?? (_ => { });
 246        set => _configureAuthorizationOptions = value;
 47    }
 48
 49    /// <summary>
 50    /// Configures the API key provider type.
 51    /// </summary>
 52    /// <typeparam name="T">The type of the API key provider.</typeparam>
 53    /// <returns>The current <see cref="DefaultAuthenticationFeature"/>.</returns>
 54    public DefaultAuthenticationFeature UseApiKeyAuthorization<T>() where T : class, IApiKeyProvider
 55    {
 356        ApiKeyProviderType = typeof(T);
 657        _configureApiKeyAuthorization = builder => builder.AddApiKeyInAuthorizationHeader<T>();
 358        return this;
 59    }
 60
 61    /// <summary>
 62    /// Configures the API key provider type to <see cref="AdminApiKeyProvider"/>. The provider denies all keys unless c
 63    /// </summary>
 64    /// <returns>The current <see cref="DefaultAuthenticationFeature"/>.</returns>
 365    public DefaultAuthenticationFeature UseAdminApiKey() => UseApiKeyAuthorization<AdminApiKeyProvider>();
 66
 67    /// <summary>
 68    /// Configures the admin API key provider with an explicit API key.
 69    /// </summary>
 70    /// <param name="apiKey">The API key to accept.</param>
 71    /// <returns>The current <see cref="DefaultAuthenticationFeature"/>.</returns>
 72    public DefaultAuthenticationFeature UseAdminApiKey(string apiKey)
 73    {
 674        Services.Configure<AdminApiKeyOptions>(options => options.ApiKey = apiKey);
 375        return UseAdminApiKey();
 76    }
 77
 78    /// <summary>
 79    /// Configures the admin API key provider with an explicit API key.
 80    /// </summary>
 81    /// <param name="configure">The admin API key options to configure.</param>
 82    /// <returns>The current <see cref="DefaultAuthenticationFeature"/>.</returns>
 83    public DefaultAuthenticationFeature UseAdminApiKey(Action<AdminApiKeyOptions> configure)
 84    {
 085        Services.Configure(configure);
 086        return UseAdminApiKey();
 87    }
 88
 89    /// <summary>
 90    /// Enables the all-zero development admin API key. Do not use in production.
 91    /// </summary>
 92    /// <returns>The current <see cref="DefaultAuthenticationFeature"/>.</returns>
 393    public DefaultAuthenticationFeature UseDevelopmentAdminApiKey() => UseAdminApiKey(AdminApiKeyProvider.DevelopmentApi
 94
 95    /// <inheritdoc />
 96    public override void Apply()
 97    {
 398        Services.ConfigureOptions<ConfigureJwtBearerOptions>();
 699        Services.Configure<AdminApiKeyOptions>(_ => { });
 3100        Services.AddIdentityTokenOptionsValidation();
 101
 3102        var authBuilder = Services
 3103            .AddAuthentication(MultiScheme)
 3104            .AddPolicyScheme(MultiScheme, MultiScheme, options =>
 3105            {
 1106                options.ForwardDefaultSelector = context =>
 1107                {
 594108                    return context.Request.Headers.Authorization.Any(x => x!.Contains(ApiKeyDefaults.AuthenticationSchem
 297109                        ? ApiKeyDefaults.AuthenticationScheme
 297110                        : JwtBearerDefaults.AuthenticationScheme;
 1111                };
 1112            })
 3113            .AddJwtBearer()
 3114            .AddJwtBearer(IdentityAuthenticationSchemes.RefreshToken);
 115
 3116        _configureApiKeyAuthorization(authBuilder);
 117
 3118        Services.AddScoped(ApiKeyProviderType);
 3119        Services.AddScoped<IApiKeyProvider>(sp => (IApiKeyProvider)sp.GetRequiredService(ApiKeyProviderType));
 3120        Services.AddAuthorization(ConfigureAuthorizationOptions);
 3121    }
 122}