using AspNetCore.Authentication.ApiKey; using Elsa.Extensions; using Elsa.Features.Abstractions; using Elsa.Features.Attributes; using Elsa.Features.Services; using Elsa.Identity.Providers; using Elsa.Requirements; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; namespace Elsa.Identity.Features; /// /// Provides an authorization feature that configures the system with JWT bearer and API key authentication. /// [DependsOn(typeof(IdentityFeature))] public class DefaultAuthenticationFeature : FeatureBase { private const string MultiScheme = "Jwt-or-ApiKey"; private Func _configureApiKeyAuthorization = builder => builder.AddApiKeyInAuthorizationHeader(); /// public DefaultAuthenticationFeature(IModule module) : base(module) { } /// /// Gets or sets the . /// public Type ApiKeyProviderType { get; set; } = typeof(DefaultApiKeyProvider); /// /// Configures the API key provider type. /// /// The type of the API key provider. /// The current . public DefaultAuthenticationFeature UseApiKeyAuthorization() where T : class, IApiKeyProvider { _configureApiKeyAuthorization = builder => builder.AddApiKeyInAuthorizationHeader(); return this; } /// /// Configures the API key provider type to . /// /// The current . public DefaultAuthenticationFeature UseAdminApiKeyAuthorization() => UseApiKeyAuthorization(); /// public override void Apply() { Services.ConfigureOptions(); Services.ConfigureOptions(); var authBuilder = Services .AddAuthentication(MultiScheme) .AddPolicyScheme(MultiScheme, MultiScheme, options => { options.ForwardDefaultSelector = context => { return context.Request.Headers.Authorization.Any(x => x!.Contains(ApiKeyDefaults.AuthenticationScheme)) ? ApiKeyDefaults.AuthenticationScheme : JwtBearerDefaults.AuthenticationScheme; }; }) .AddJwtBearer(); _configureApiKeyAuthorization(authBuilder); Services.AddSingleton(); Services.AddSingleton(ApiKeyProviderType); Services.AddSingleton(sp => (IApiKeyProvider)sp.GetRequiredService(ApiKeyProviderType)); Services.AddAuthorization(options => options.AddPolicy(IdentityPolicyNames.SecurityRoot, policy => policy.AddRequirements(new LocalHostRequirement()))); } }