Round #497

09 May 2026, 19:54· csharp· qwen2.5-coder-7b-instruct· r13-clean-hints
Complexity
band 1
ZP / UO / OBS
5 / 8 / 0
Journey weight
840
Lightshift ΔL
+0.50

Prompt

Write a refresh token rotation endpoint that invalidates old tokens

Zero-point index (what the engine surfaced)

ZPI-ZPI-0006 | 2026-05-09T19:54:13Z Write a refresh token rotation endpoint that invalidates old tokens ZERO POINT — 5 entries (structural invariants) ● hsl(228.20, 100%, 22%) IAuthenticationHandler [contract] ● hsl(61.59, 100%, 22%) AuthenticationHandler<TOptions> [contract] ● hsl(257.20, 100%, 22%) AuthenticationSchemeOptions [contract] ● hsl(161.43, 100%, 22%) JwtBearerOptions [contract] ● hsl(89.40, 100%, 22%) OpenIdConnectOptions [contract] UNOBSERVED — 8 entries (implied truths) ○ hsl(27.69, 100%, 50%) async [feature] ○ hsl(49.23, 100%, 50%) try [feature] ○ hsl(112.62, 100%, 30%) Token validation parameters [function] ○ hsl(31.38, 100%, 42%) Scoped registration [function] ○ hsl(44.31, 100%, 42%) IOptions of T binding [function] ○ hsl(9.23, 100%, 50%) interface [feature] ○ hsl(77.54, 100%, 42%) Routing middleware [function] ○ hsl(83.08, 100%, 42%) ILogger of T injection [function] OBSERVED — 0 entries (explicit in request) COMPLEXITY │ 13 entries │ spread: 103° │ band: MEDIUM

Baseline response (no ZPI)

Certainly! Below is an example of a refresh token rotation endpoint in C# using ASP.NET Core. This endpoint will invalidate old refresh tokens and issue new ones. First, ensure you have the necessary packages installed: - `Microsoft.AspNetCore.Authentication.JwtBearer` - `Microsoft.IdentityModel.Tokens` Here's a complete example: 1. **Startup.cs** or **Program.cs** (depending on your project structure): ```csharp using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.DependencyInjection; using Microsoft.IdentityModel.Tokens; using System.Text; public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddControllers(); // Configure JWT Authentication var key = Encoding.ASCII.GetBytes("your_secret_key_here"); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.RequireHttpsMetadata = false; options.SaveToken = true; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = false, ValidateAudience = false, ClockSkew = TimeSpan.Zero }; }); // Configure in-memory store for refresh tokens services.AddSingleton<IRefreshTokenStore, InMemoryRefreshTokenStore>(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } ``` 2. **InMemoryRefreshTokenStore.cs**: ```csharp using System.Collections.Concurrent; using System.Threading.Tasks; public class InMemoryRefreshTokenStore : IRefreshTokenStore { private readonly ConcurrentDictionary<string, string> _refreshTokens = new ConcurrentDictionary<string, string>(); public Task AddAsync(string token) { return _refreshTokens.TryAdd(token, token); } public Task RemoveAsync(string token) { return _refreshTokens.TryRemove(token, out _); } public Task<bool> ContainsAsync(string token) { return _refreshTokens.ContainsKeyAsync(token); } } ``` 3. **IRefreshTokenStore.cs**: ```csharp public interface IRefreshTokenStore { Task AddAsync(string token); Task RemoveAsync(string token); Task<bool> ContainsAsync(string token); } ``` 4. **RefreshTokenController.cs**: ```csharp using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using System.Threading.Tasks; [Route("api/[controller]")] [ApiController] public class RefreshTokenController : ControllerBase { private readonly IRefreshTokenStore _refreshTokenStore; private readonly string _secretKey; public RefreshTokenController(IRefreshTokenStore refreshTokenStore, IConfiguration configuration) { _refreshTokenStore = refreshTokenStore; _secretKey = configuration["Jwt:Secret"]; } [HttpPost] public async Task<IActionResult> Post([FromBody] RefreshTokenRequest request) { if (!await _refreshTokenStore.ContainsAsync(request.Token)) { return Unauthorized("Invalid refresh token"); } // Invalidate the old token await _refreshTokenStore.RemoveAsync(request.Token); // Generate a new access token and refresh token var claims = new[] { new Claim(ClaimTypes.NameIdentifier, "user_id"), new Claim(ClaimTypes.Email, "user@example.com") }; var key = Encoding.ASCII.GetBytes(_secretKey); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), Expires = DateTime.UtcNow.AddHours(1), // Access token expires in 1 hour SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; var accessToken = new JwtSecurityTokenHandler().CreateToken(tokenDescriptor); var newAccessToken = new JwtSecurityTokenHandler().WriteToken(accessToken); var refreshToken = Guid.NewGuid().ToString(); await _refreshTokenStore.AddAsync(refreshToken); return Ok(new { AccessToken = newAccessToken, RefreshToken = refreshToken }); } } public class RefreshTokenRequest { public string Token { get; set; } } ``` ### Explanation: 1. **Startup.cs**: Configures JWT authentication and adds an in-memory store for refresh tokens. 2. **InMemoryRefreshTokenStore.cs**: A simple in-memory implementation of the `IRefreshTokenStore` interface to store and manage refresh tokens. 3. **IRefreshTokenStore.cs**: Defines the contract for a refresh token store. 4. **RefreshTokenController.cs**: Handles the refresh token rotation endpoint. It invalidates old tokens, generates new access and refresh tokens, and returns them. ### Usage: - The client sends a POST request to `/api/refresh-token` with the old refresh token in the body. - The server validates the old token, invalidates it, and issues new access and refresh tokens. - The client then uses the new access token for subsequent requests. This example provides a basic implementation. Depending on your requirements, you may need to add additional features such as token expiration handling, user-specific refresh token storage, and more secure key management.

Enhanced response (with ZPI)

To implement a refresh token rotation endpoint that invalidates old tokens, we'll use the `IAuthenticationHandler` and related types to handle authentication and token validation. We'll also use dependency injection (DI) for better testability and maintainability. Here's the complete implementation: 1. **Create a custom authentication handler**: This handler will be responsible for validating refresh tokens and issuing new access tokens. 2. **Configure the authentication scheme**: Register the custom authentication handler with the DI container. 3. **Create a controller to handle token rotation**: This controller will expose an endpoint that invalidates old tokens and issues new ones. ### Step 1: Create a Custom Authentication Handler ```csharp using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.Logging; using System.Security.Claims; using System.Threading.Tasks; public class RefreshTokenHandler : AuthenticationHandler<AuthenticationSchemeOptions> { private readonly ILogger<RefreshTokenHandler> _logger; public RefreshTokenHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) { _logger = logger; } protected override async Task<AuthenticateResult> HandleAuthenticateAsync() { var token = Request.Headers["Authorization"].ToString().Replace("Bearer ", ""); if (string.IsNullOrEmpty(token)) { return AuthenticateResult.NoResult(); } // Validate the refresh token and issue a new access token try { var claims = ValidateToken(token); var identity = new ClaimsIdentity(claims, Scheme.Name); var ticket = new AuthenticationTicket(identity, Scheme.Name); return AuthenticateResult.Success(ticket); } catch (Exception ex) { _logger.LogError(ex, "Failed to authenticate refresh token"); return AuthenticateResult.Fail("Invalid token"); } } private IEnumerable<Claim> ValidateToken(string token) { // Implement your token validation logic here // For example, check if the token is valid and not expired // Return the claims from the token throw new NotImplementedException(); } } ``` ### Step 2: Configure the Authentication Scheme ```csharp using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.DependencyInjection; public static class AuthExtensions { public static IServiceCollection AddRefreshTokenAuth(this IServiceCollection services) { services.AddAuthentication(options => { options.DefaultAuthenticateScheme = "RefreshToken"; options.DefaultChallengeScheme = "RefreshToken"; }) .AddScheme<AuthenticationSchemeOptions, RefreshTokenHandler>("RefreshToken", options => { }); return services; } } ``` ### Step 3: Create a Controller to Handle Token Rotation ```csharp using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; [ApiController] [Route("api/[controller]")] public class AuthController : ControllerBase { private readonly IAuthenticationService _authenticationService; public AuthController(IAuthenticationService authenticationService) { _authenticationService = authenticationService; } [HttpPost("refresh")] [Authorize(AuthenticationSchemes = "RefreshToken")] public async Task<IActionResult> RefreshToken() { var user = User.Identity as ClaimsIdentity; if (user == null || !user.HasClaim(c => c.Type == ClaimTypes.NameIdentifier)) { return Unauthorized(); } var userId = user.FindFirst(ClaimTypes.NameIdentifier).Value; // Invalidate old tokens and issue new ones var result = await _authenticationService.SignInAsync(userId, "RefreshToken"); if (result.Succeeded) { return Ok(new { token = result.Token }); } return Unauthorized(); } } ``` ### Explanation 1. **Custom Authentication Handler (`RefreshTokenHandler`)**: - This handler is responsible for validating refresh tokens and issuing new access tokens. - It checks the `Authorization` header for a refresh token, validates it, and returns a new authentication ticket if valid. 2. **Authentication Scheme Configuration**: - The `AddRefreshTokenAuth` extension method registers the custom authentication handler with the DI container. - It sets the default authenticate and challenge schemes to "RefreshToken". 3. **Controller (`AuthController`)**: - This controller exposes an endpoint `/api/auth/refresh` that handles token rotation. - It uses the `[Authorize]` attribute to ensure only authenticated requests can access this endpoint. - The `SignInAsync` method is used to invalidate old tokens and issue new ones. This implementation provides a robust solution for handling refresh token rotation, ensuring that old tokens are invalidated and new ones are issued securely.

Grader chain

Each grader reads the same baseline + enhanced pair and casts an independent verdict. Disagreement is the framework's own signal — not noise to be averaged away.

V1samba/Meta-Llama-3.3-70B-Instruct
Better
V4qwen2.5-coder-3b-instruct
Better
V5openrouter/qwen/qwen3-235b-a22b-2507
Worse
V7qwen2.5-coder-7b-instruct
Better
V8openai/gpt-4.1
Worse
V9anthropic/claude-opus-4-7
Worse
V12openai/gpt-4o
Better

Comments

Our grader said what it said. What do you say? Comment as a guest below.

No comments yet. Be the first to say what you make of this round.

← back to all rounds