AutoLog issues HMAC-SHA256 signed JWTs using .NET’sDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/JReyna217/AutoLog/llms.txt
Use this file to discover all available pages before exploring further.
System.IdentityModel.Tokens.Jwt library. The token lifecycle is split into two tiers: short-lived access tokens that authorize individual API calls, and long-lived refresh tokens that are stored in the PostgreSQL database and rotated on every use. Both token types are returned together as a TokenResponseDto on login and on each successful refresh.
JwtSettings Configuration Reference
All JWT behaviour is controlled by theJwtSettings block in appsettings.json. In production, override every value through environment variables so that secrets never live in source control.
| Key | Default (appsettings.json) | Environment Variable | Description |
|---|---|---|---|
Secret | (empty — must be set) | JwtSettings__Secret | HMAC-SHA256 signing key. Must be at least 32 characters. Use a randomly generated string of 64+ characters in production. |
Issuer | AutoLog.API | JwtSettings__Issuer | The iss claim value embedded in every access token. The bearer middleware validates this on every request. |
Audience | AutoLog.AngularClient | JwtSettings__Audience | The aud claim value embedded in every access token. Must match the ValidAudience set in Program.cs. |
ExpiryMinutes | 15 | JwtSettings__ExpiryMinutes | Lifetime of the access token in minutes. Decrease for stricter security; increase only if UX demands it. |
RefreshExpiryDays | 7 | JwtSettings__RefreshExpiryDays | Lifetime of the refresh token in days. After expiry the user must log in again. |
appsettings.json block looks like this:
Access Token Claims
Every access token generated byJwtService.GenerateAccessToken carries the following claims:
| Claim | JWT Registered Name | Value | Description |
|---|---|---|---|
sub | JwtRegisteredClaimNames.Sub | User’s integer ID (string) | Standard subject identifier — uniquely identifies the authenticated user. |
email | JwtRegisteredClaimNames.Email | User’s email address | Used for display purposes and identity resolution. |
name | JwtRegisteredClaimNames.Name | User’s full name | The FullName value stored on the User entity. |
UserId | Custom claim | User’s integer ID (string) | Duplicate of sub added for convenient extraction in middleware and the global exception handler without relying on the standard sub name. |
JwtService.cs:
Token Rotation
CallingPOST /api/auth/refresh triggers a full token rotation cycle. AutoLog does not reuse refresh tokens — each call produces an entirely new pair.
The rotation logic in RefreshTokenCommandHandler:
- The expired access token is passed through
JwtService.GetPrincipalFromExpiredToken, which validates the token’s signature and claims but explicitly skips lifetime validation (ValidateLifetime = false). - The
UserIdcustom claim is extracted to look up the user in the database. - The stored
RefreshTokenvalue is compared to the token sent in the request. If they don’t match, or theRefreshTokenExpiryTimehas passed, the request is rejected with401. - A new access token and a new refresh token are generated.
- The user record is updated with the new
RefreshTokenand a newRefreshTokenExpiryTime(DateTime.UtcNow.AddDays(RefreshExpiryDays)), then persisted to the database. - The new
TokenResponseDtois returned to the client.
Refresh tokens are opaque 64-byte cryptographically random values generated with
RandomNumberGenerator.Create() and Base64-encoded. They are never signed JWTs and carry no embedded claims.Token Validation Parameters
The following validation parameters are registered inProgram.cs for the JwtBearerDefaults.AuthenticationScheme and are applied to every incoming request on protected endpoints:
| Parameter | Value | Effect |
|---|---|---|
ValidateIssuer | true | Rejects tokens whose iss claim does not match JwtSettings:Issuer. |
ValidateAudience | true | Rejects tokens whose aud claim does not match JwtSettings:Audience. |
ValidateLifetime | true | Rejects tokens whose exp claim is in the past. |
ValidateIssuerSigningKey | true | Rejects tokens whose HMAC-SHA256 signature cannot be verified with the configured secret. |
During token refresh,
ValidateLifetime is intentionally set to false inside JwtService.GetPrincipalFromExpiredToken — this is the only code path where an expired access token is accepted. The algorithm is still verified to be HmacSha256; any token with a different algorithm header is rejected with a 401.Security Considerations
Access tokens are intentionally short-lived (15 minutes by default) to minimise exposure if a token is intercepted. Adjust
JwtSettings:ExpiryMinutes upward only when UX requirements genuinely demand it, and pair any increase with stricter transport security (HTTPS-only, HSTS).