< Summary

Information
Class: Intentum.AspNetCore.Auth.IntentumAuthExtensions
Assembly: Intentum.AspNetCore
File(s): /home/runner/work/Intentum/Intentum/src/Intentum.AspNetCore/Auth/IntentumAuthExtensions.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 52
Coverable lines: 52
Total lines: 98
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 8
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
AddIntentumApiKeyAuth(...)100%110%
AddIntentumAuth(...)0%880%

File(s)

/home/runner/work/Intentum/Intentum/src/Intentum.AspNetCore/Auth/IntentumAuthExtensions.cs

#LineLine coverage
 1using Microsoft.AspNetCore.Authentication;
 2using Microsoft.AspNetCore.Authentication.JwtBearer;
 3using Microsoft.Extensions.DependencyInjection;
 4using Microsoft.IdentityModel.Tokens;
 5using System.Text;
 6
 7namespace Intentum.AspNetCore.Auth;
 8
 9/// <summary>
 10/// Extension methods for configuring Intentum authentication (JWT + API key).
 11/// </summary>
 12public static class IntentumAuthExtensions
 13{
 14    private const string RoleAdmin = "Admin";
 15
 16    /// <summary>
 17    /// Adds Intentum authentication with API key support.
 18    /// </summary>
 19    public static AuthenticationBuilder AddIntentumApiKeyAuth(
 20        this IServiceCollection services,
 21        Action<ApiKeyAuthenticationOptions> configure)
 022    {
 023        return services.AddAuthentication(ApiKeyAuthenticationHandler.SchemeName)
 024            .AddScheme<ApiKeyAuthenticationOptions, ApiKeyAuthenticationHandler>(
 025                ApiKeyAuthenticationHandler.SchemeName, configure);
 026    }
 27
 28    /// <summary>
 29    /// Adds Intentum authentication with both JWT and API key support.
 30    /// </summary>
 31    public static AuthenticationBuilder AddIntentumAuth(
 32        this IServiceCollection services,
 33        Action<IntentumAuthOptions> configure)
 034    {
 035        var options = new IntentumAuthOptions();
 036        configure(options);
 37
 038        var builder = services.AddAuthentication(opts =>
 039        {
 040            opts.DefaultScheme = "IntentumComposite";
 041            opts.DefaultChallengeScheme = "IntentumComposite";
 042        });
 43
 044        if (!string.IsNullOrEmpty(options.JwtSecret))
 045        {
 046            builder.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, jwt =>
 047            {
 048                jwt.TokenValidationParameters = new TokenValidationParameters
 049                {
 050                    ValidateIssuer = !string.IsNullOrEmpty(options.JwtIssuer),
 051                    ValidIssuer = options.JwtIssuer,
 052                    ValidateAudience = !string.IsNullOrEmpty(options.JwtAudience),
 053                    ValidAudience = options.JwtAudience,
 054                    ValidateIssuerSigningKey = true,
 055                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(options.JwtSecret)),
 056                    ValidateLifetime = true
 057                };
 058            });
 059        }
 60
 061        builder.AddScheme<ApiKeyAuthenticationOptions, ApiKeyAuthenticationHandler>(
 062            ApiKeyAuthenticationHandler.SchemeName, apiKeyOpts =>
 063            {
 064                apiKeyOpts.ValidKeys = options.ApiKeys;
 065            });
 66
 067        builder.AddPolicyScheme("IntentumComposite", "JWT or API Key", policyOpts =>
 068        {
 069            policyOpts.ForwardDefaultSelector = context =>
 070            {
 071                if (context.Request.Headers.ContainsKey("Authorization"))
 072                    return JwtBearerDefaults.AuthenticationScheme;
 073                if (context.Request.Headers.ContainsKey("X-Api-Key") ||
 074                    context.Request.Query.ContainsKey("api_key"))
 075                    return ApiKeyAuthenticationHandler.SchemeName;
 076                return JwtBearerDefaults.AuthenticationScheme;
 077            };
 078        });
 79
 080        services.AddAuthorizationBuilder()
 081            .AddPolicy(RoleAdmin, policy => policy.RequireRole(RoleAdmin))
 082            .AddPolicy("Analyst", policy => policy.RequireRole(RoleAdmin, "Analyst"))
 083            .AddPolicy("ReadOnly", policy => policy.RequireRole(RoleAdmin, "Analyst", "ReadOnly"));
 84
 085        return builder;
 086    }
 87}
 88
 89/// <summary>
 90/// Combined authentication options for JWT + API key.
 91/// </summary>
 92public sealed class IntentumAuthOptions
 93{
 94    public string? JwtSecret { get; set; }
 95    public string? JwtIssuer { get; set; }
 96    public string? JwtAudience { get; set; }
 97    public List<ApiKeyEntry> ApiKeys { get; set; } = [];
 98}