Securing .NET Applications with JWT Refresh Token Rotation
These articles are AI-generated summaries. Please check the original sources for full details.
JWT Refresh Token Rotation in .NET — Why Your Auth is Probably Broken
Standard JWT implementations often leave accounts vulnerable for up to 7 days if a refresh token is compromised. Token rotation mitigates this risk by revoking and replacing tokens on every use, enabling immediate detection of theft through token lineage tracking.
Why This Matters
In many production environments, developers rely on long-lived static refresh tokens, creating a persistent attack vector. While ideal models assume secure storage, technical reality involves risks like XSS or physical device access; rotating tokens ensures that even if a token is stolen, its utility is limited to a single transaction before triggering an automated security alert that can revoke the entire token family.
Key Insights
- Default ClockSkew in .NET is 5 minutes, which allows expired tokens to remain valid unless explicitly set to TimeSpan.Zero during configuration.
- Token lineage tracking via the ReplacedByToken field creates a chain of custody that identifies compromised token reuse and triggers automated revocation.
- Cryptographically secure token generation using RandomNumberGenerator.GetBytes(64) ensures high entropy for refresh tokens compared to standard GUIDs.
- Short-lived access tokens (15 minutes) minimize the potential damage window if a bearer token is intercepted in transit.
Working Examples
The RefreshToken entity includes a ReplacedByToken field to create a chain for rotation tracking and compromise detection.
public class RefreshToken
{
public Guid Id { get; set; } = Guid.NewGuid();
public string Token { get; set; }
public DateTime ExpiresAt { get; set; }
public bool IsRevoked { get; set; }
public DateTime? RevokedAt { get; set; }
public string? ReplacedByToken { get; set; }
public Guid UserId { get; set; }
public ApplicationUser User { get; set; }
public bool IsExpired => DateTime.UtcNow >= ExpiresAt;
public bool IsActive => !IsRevoked && !IsExpired;
}
Implementation of secure refresh token generation using 64-bit random byte arrays.
public async Task<RefreshToken> GenerateRefreshTokenAsync(
Guid userId, CancellationToken ct = default)
{
var refreshToken = new RefreshToken
{
Token = Convert.ToBase64String(
RandomNumberGenerator.GetBytes(64)),
ExpiresAt = DateTime.UtcNow.AddDays(7),
UserId = userId
};
_context.RefreshTokens.Add(refreshToken);
await _context.SaveChangesAsync(ct);
return refreshToken;
}
Practical Applications
- Use Case: Storing refresh tokens in httpOnly cookies to prevent JavaScript-based XSS attacks that target localStorage.
- Pitfall: Failing to invalidate all refresh tokens upon a password change, which leaves existing sessions active for potential attackers.
- Use Case: Enforcing environment-specific JWT secrets to ensure that a compromise in a development environment does not affect production security.
References:
Continue reading
Next article
LangChain Deep Agents: A Structured Runtime for Multi-Step AI Agent Orchestration
Related Content
Securing Microsoft Fabric: Implementing Outbound Access Protection for Semantic Models
Microsoft's preview of Outbound Access Protection shifts Power BI governance from report permissions to workspace-level network controls.
Beyond Container Isolation: Securing AI Email Agents with Least Privilege
Learn why mailbox permissions and draft-only flows are more critical for OpenClaw security than Docker isolation to prevent prompt injection incidents.
Automated Domain Portfolio Monitoring: Preventing Expiration and Account Breaches
Monitor WHOIS expiration and registration email breaches to prevent silent domain loss and SEO damage using EdgeIQ Labs tools.