< Summary

Information
Class: Elsa.Identity.Options.IdentityTokenOptions
Assembly: Elsa.Identity
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Identity/Options/IdentityTokenOptions.cs
Line coverage
97%
Covered lines: 34
Uncovered lines: 1
Coverable lines: 35
Total lines: 99
Line coverage: 97.1%
Branch coverage
50%
Covered branches: 3
Total branches: 6
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_SigningKey()100%11100%
get_Issuer()100%11100%
get_Audience()100%11100%
get_AccessTokenLifetime()100%11100%
get_RefreshTokenLifetime()100%11100%
get_TenantIdClaimsType()100%11100%
CreateSecurityKey()100%11100%
ConfigureJwtBearerOptions(...)100%210%
ConfigureJwtBearerOptions(...)50%22100%
CreateTokenValidationParameters()100%11100%
ValidateLifetime(...)50%44100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Identity/Options/IdentityTokenOptions.cs

#LineLine coverage
 1using System.IdentityModel.Tokens.Jwt;
 2using System.Text;
 3using Elsa.Identity.Constants;
 4using Microsoft.AspNetCore.Authentication.JwtBearer;
 5using Microsoft.IdentityModel.Tokens;
 6
 7namespace Elsa.Identity.Options;
 8
 9/// <summary>
 10/// Represents options about token validation and generation.
 11/// </summary>
 12public class IdentityTokenOptions
 13{
 14    /// <summary>
 15    /// The key to use when signing tokens
 16    /// </summary>
 14617    public string SigningKey { get; set; } = null!;
 18
 19    /// <summary>
 20    /// The issuer to use when creating and validating tokens
 21    /// </summary>
 8122    public string Issuer { get; set; } = "http://elsa.api";
 23
 24    /// <summary>
 25    /// The audience to use when creating and validating tokens
 26    /// </summary>
 8127    public string Audience { get; set; } = "http://elsa.api";
 28
 29    /// <summary>
 30    /// The lifetime of access tokens
 31    /// </summary>
 5332    public TimeSpan AccessTokenLifetime { get; set; } = TimeSpan.FromMinutes(15);
 33
 34    /// <summary>
 35    /// The lifetime of refresh tokens
 36    /// </summary>
 5137    public TimeSpan RefreshTokenLifetime { get; set; } = TimeSpan.FromHours(2);
 38
 39    /// <summary>
 40    /// Gets or sets the claim type that hold the tenant ID in the user's claims.
 41    /// If not set, <see cref="CustomClaimTypes.TenantId" /> will be used
 42    /// </summary>
 6143    public string TenantIdClaimsType { get; set; } = CustomClaimTypes.TenantId;
 44
 45    /// <summary>
 46    /// Creates a new <see cref="SecurityKey"/> from the <see cref="SigningKey"/>.
 47    /// </summary>
 48    /// <returns></returns>
 2349    public SecurityKey CreateSecurityKey() => new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SigningKey));
 50
 51    /// <summary>
 52    /// Configures the <see cref="JwtBearerOptions"/> with the values from this instance.
 53    /// </summary>
 54    /// <param name="options">The options to configure.</param>
 055    public void ConfigureJwtBearerOptions(JwtBearerOptions options) => ConfigureJwtBearerOptions(options, TokenUse.Acces
 56
 57    /// <summary>
 58    /// Configures the <see cref="JwtBearerOptions"/> with the values from this instance.
 59    /// </summary>
 60    /// <param name="options">The options to configure.</param>
 61    /// <param name="requiredTokenUse">The required token usage claim value.</param>
 62    public void ConfigureJwtBearerOptions(JwtBearerOptions options, string requiredTokenUse)
 63    {
 964        options.TokenValidationParameters = CreateTokenValidationParameters();
 965        options.Events ??= new JwtBearerEvents();
 966        var previousOnTokenValidated = options.Events.OnTokenValidated;
 967        options.Events.OnTokenValidated = async context =>
 968        {
 969            await previousOnTokenValidated(context);
 970
 971            if (context.Result?.Failure != null || context.Result?.None == true)
 172                return;
 973
 874            var tokenUse = context.Principal?.FindFirst(TokenUse.ClaimType)?.Value;
 975
 876            if (!string.Equals(tokenUse, requiredTokenUse, StringComparison.Ordinal))
 677                context.Fail($"The token is not a valid {requiredTokenUse} token.");
 1878        };
 979    }
 80
 81    /// <summary>
 82    /// Creates token validation parameters for Elsa identity tokens.
 83    /// </summary>
 1184    public TokenValidationParameters CreateTokenValidationParameters() => new()
 1185    {
 1186        IssuerSigningKey = CreateSecurityKey(),
 1187        ValidAudience = Audience,
 1188        ValidIssuer = Issuer,
 1189        ValidateIssuerSigningKey = true,
 1190        ValidateLifetime = true,
 1191        LifetimeValidator = ValidateLifetime,
 1192        NameClaimType = JwtRegisteredClaimNames.Name
 1193    };
 94
 95    private static bool ValidateLifetime(DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValid
 96    {
 1097        return expires != null && expires > DateTime.UtcNow;
 98    }
 99}