How-to guide

Sign development JWTs

To try a host locally without an identity provider, validate tokens with a symmetric key that lives in source and mint tokens with the same key. Anyone who reads that key can sign a token for any user, so it must never validate tokens outside Development.

Register the key in Development only

Put do-not-use-in-production in the key, register it only when the environment is Development, and register the real issuer everywhere else:

using Trax.Api.Auth.Jwt;
 
if (builder.Environment.IsDevelopment())
    builder.Services.AddTraxJwtAuth(jwt =>
        jwt.UseSymmetricKey(DevJwt.Issuer, DevJwt.Audience, DevJwt.Key));
else
    builder.Services.AddTraxJwtAuth(
        builder.Configuration["Auth:Jwt:Authority"]!,
        builder.Configuration["Auth:Jwt:Audience"]!);

The marker is a backstop: a host that validates with a symmetric key containing it refuses to start outside Development, wherever the key was configured (AddTraxJwtAuth).

Mint tokens with it

Sign tokens with the claims DefaultJwtPrincipalResolver reads: sub becomes the id, name the display name, each role a role:

using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
 
public static class DevJwt
{
    public const string Issuer = "my-app-dev";
    public const string Audience = "my-app";
 
    public static readonly byte[] Key =
        Encoding.UTF8.GetBytes("my-app-dev-signing-key-do-not-use-in-production");
 
    public static string Mint(string sub, params string[] roles) =>
        new JsonWebTokenHandler().CreateToken(new SecurityTokenDescriptor
        {
            Issuer = Issuer,
            Audience = Audience,
            Subject = new ClaimsIdentity(
                [new Claim("sub", sub), new Claim("name", sub), .. roles.Select(r => new Claim("role", r))]),
            Expires = DateTime.UtcNow.AddHours(1),
            SigningCredentials = new SigningCredentials(
                new SymmetricSecurityKey(Key), SecurityAlgorithms.HmacSha256),
        });
}

The Auth sample serves such tokens from a GET /dev/token/{user} endpoint it maps only in Development. In tests, TestTokenIssuer .Symmetric mints them.

SDK Reference

AddTraxJwtAuth | TestTokenIssuer