Round #716

10 May 2026, 15:12· csharp· Meta-Llama-3.3-70B-Instruct· r13-clean-hints
Complexity
band 0
ZP / UO / OBS
5 / 0 / 2
Journey weight
447
Lightshift ΔL
+0.40

Prompt

Implement a JwtBearerOptions handler that validates a custom claim transformation using IClaimsTransformation in DI.

Zero-point index (what the engine surfaced)

ZPI-ZPI-0015 | 2026-05-10T15:12:28Z Implement a JwtBearerOptions handler that validates a custom claim transformation using IClaimsTransformation in DI. ZERO POINT — 5 entries (structural invariants) ● hsl(228.20, 100%, 30%) IAuthenticationHandler [contract] ● hsl(61.59, 100%, 30%) AuthenticationHandler<TOptions> [contract] ● hsl(257.20, 100%, 30%) AuthenticationSchemeOptions [contract] ● hsl(161.43, 100%, 30%) JwtBearerOptions [contract] ● hsl(89.40, 100%, 30%) OpenIdConnectOptions [contract] UNOBSERVED — 0 entries (implied truths) OBSERVED — 2 entries (explicit in request) ◉ hsl(85.13, 100%, 50%) using [feature] ◉ hsl(234.87, 100%, 50%) using [feature] COMPLEXITY │ 7 entries │ spread: 150° │ band: LOW

Baseline response (no ZPI)

**Custom Claim Transformation using IClaimsTransformation** =========================================================== In this example, we will implement a custom claim transformation using `IClaimsTransformation` and validate it using `JwtBearerOptions` in a .NET Core application. **IClaimsTransformation Implementation** -------------------------------------- First, let's create a custom implementation of `IClaimsTransformation` that adds a custom claim to the principal: ```csharp using Microsoft.AspNetCore.Authentication; using System; using System.Collections.Generic; using System.Security.Claims; using System.Threading.Tasks; public class CustomClaimsTransformation : IClaimsTransformation { public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) { var claims = principal.Claims.ToList(); // Add a custom claim claims.Add(new Claim("custom_claim", "custom_value")); var newIdentity = new ClaimsIdentity(claims, principal.Identity.AuthenticationType); var newPrincipal = new ClaimsPrincipal(newIdentity); return newPrincipal; } } ``` **JwtBearerOptions Configuration** --------------------------------- Next, let's configure `JwtBearerOptions` to use our custom claim transformation: ```csharp using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.DependencyInjection; public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.Audience = "your_audience"; options.Authority = "your_authority"; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_secret_key")) }; // Use our custom claim transformation options.Events = new JwtBearerEvents { OnTokenValidated = async context => { var claimsTransformation = context.HttpContext.RequestServices.GetService<IClaimsTransformation>(); var newPrincipal = await claimsTransformation.TransformAsync(context.Principal); context.Principal = newPrincipal; } }; }); // Register our custom claim transformation services.AddTransient<IClaimsTransformation, CustomClaimsTransformation>(); } ``` **Example Usage** ----------------- To test our custom claim transformation, we can create a simple controller that returns the claims of the authenticated user: ```csharp using Microsoft.AspNetCore.Mvc; using System.Security.Claims; [ApiController] [Route("api/[controller]")] public class ClaimsController : ControllerBase { [Authorize] [HttpGet] public IActionResult GetClaims() { var claims = User.Claims.ToList(); return Ok(claims); } } ``` When we make a GET request to `/api/claims`, we should see the custom claim `custom_claim` with value `custom_value` in the response. **Full Code Example** --------------------- Here is the full code example: ```csharp using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Security.Claims; using System.Threading.Tasks; namespace CustomClaimTransformationExample { public class CustomClaimsTransformation : IClaimsTransformation { public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) { var claims = principal.Claims.ToList(); // Add a custom claim claims.Add(new Claim("custom_claim", "custom_value")); var newIdentity = new ClaimsIdentity(claims, principal.Identity.AuthenticationType); var newPrincipal = new ClaimsPrincipal(newIdentity); return newPrincipal; } } public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.Audience = "your_audience"; options.Authority = "your_authority"; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_secret_key")) }; // Use our custom claim transformation options.Events = new JwtBearerEvents { OnTokenValidated = async context => { var claimsTransformation = context.HttpContext.RequestServices.GetService<IClaimsTransformation>(); var newPrincipal = await claimsTransformation.TransformAsync(context.Principal); context.Principal = newPrincipal; } }; }); // Register our custom claim transformation services.AddTransient<IClaimsTransformation, CustomClaimsTransformation>(); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } [ApiController] [Route("api/[controller]")] public class ClaimsController : ControllerBase { [Authorize] [HttpGet] public IActionResult GetClaims() { var claims = User.Claims.ToList(); return Ok(claims); } } } ``` Note that you should replace `your_audience`, `your_authority`, and `your_secret_key` with your actual JWT settings.

Enhanced response (with ZPI)

```csharp using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication; using System; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; // Custom claim transformation public class CustomClaimsTransformation : IClaimsTransformation { public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) { var claims = principal.Claims.ToList(); // Custom claim transformation logic var customClaim = new Claim("custom_claim", "custom_value"); claims.Add(customClaim); var newIdentity = new ClaimsIdentity(claims, principal.Identity.AuthenticationType); var newPrincipal = new ClaimsPrincipal(newIdentity); return await Task.FromResult(newPrincipal); } } // JwtBearerOptions handler with custom claim transformation public class CustomJwtBearerOptionsHandler : AuthenticationHandler<JwtBearerOptions> { private readonly IClaimsTransformation _claimsTransformation; public CustomJwtBearerOptionsHandler( IOptionsMonitor<JwtBearerOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IClaimsTransformation claimsTransformation) : base(options, logger, encoder, clock) { _claimsTransformation = claimsTransformation; } protected override async Task<AuthenticateResult> HandleAuthenticateAsync() { var authenticateResult = await base.HandleAuthenticateAsync(); if (authenticateResult.Succeeded) { var transformedPrincipal = await _claimsTransformation.TransformAsync(authenticateResult.Principal); return AuthenticateResult.Success(new AuthenticationTicket(transformedPrincipal, authenticateResult.Properties, Scheme.Name)); } return authenticateResult; } } // DI registration public void ConfigureServices(IServiceCollection services) { services.AddTransient<IClaimsTransformation, CustomClaimsTransformation>(); services.AddAuthentication(options => { options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.Audience = "your_audience"; options.Authority = "your_authority"; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey("your_secret_key".Sha256()) }; }); services.AddSingleton<AuthenticationHandler<JwtBearerOptions>, CustomJwtBearerOptionsHandler>(); } ``` This implementation provides a custom `IClaimsTransformation` that adds a custom claim to the principal. The `CustomJwtBearerOptionsHandler` class inherits from `AuthenticationHandler<JwtBearerOptions>` and overrides the `HandleAuthenticateAsync` method to apply the custom claim transformation after successful authentication. The `CustomClaimsTransformation` and `CustomJwtBearerOptionsHandler` are registered in the DI container in the `ConfigureServices` method.

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
Better
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