Round #847
11 May 2026, 09:45· csharp· Meta-Llama-3.3-70B-Instruct· r15-firing-v3
- Complexity
- band 0
- ZP / UO / OBS
- 3 / 0 / 0
- Journey weight
- 177
- Lightshift ΔL
- -0.17
Prompt
Implement an IAuthorizationHandler for a 'CanEditOwn' permission that checks the current user owns the resource being modified.
Zero-point index (what the engine surfaced)
ZPI-ZPI-0004 | 2026-05-11T09:45:48Z
Implement an IAuthorizationHandler for a 'CanEditOwn' permission that checks the current user owns the resource being modified.
ZERO POINT — 3 entries (structural invariants)
● hsl(178.91, 100%, 41%) IAuthorizationHandler [contract]
● hsl(14.32, 100%, 41%) IAuthorizationRequirement [contract]
● hsl(349.17, 100%, 41%) AuthorizationHandler<TRequirement> [contract]
UNOBSERVED — 0 entries (implied truths)
OBSERVED — 0 entries (explicit in request)
COMPLEXITY │ 3 entries │ spread: 0° │ band: LOW
Baseline response (no ZPI)
**Implementing IAuthorizationHandler for 'CanEditOwn' Permission**
===========================================================
Below is an example implementation of an `IAuthorizationHandler` for a 'CanEditOwn' permission in C#.
### CanEditOwnRequirement.cs
```csharp
using Microsoft.AspNetCore.Authorization;
public class CanEditOwnRequirement : IAuthorizationRequirement
{
public string ClaimValue { get; }
public CanEditOwnRequirement(string claimValue)
{
ClaimValue = claimValue;
}
}
```
### CanEditOwnHandler.cs
```csharp
using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;
public class CanEditOwnHandler : AuthorizationHandler<CanEditOwnRequirement>
{
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, CanEditOwnRequirement requirement)
{
var userIdClaim = context.User.FindFirstValue("id");
var resourceOwnerId = context.Resource as string;
if (userIdClaim == resourceOwnerId)
{
context.Succeed(requirement);
}
await Task.CompletedTask;
}
}
```
### Startup.cs (or Program.cs in .NET 6 and later)
```csharp
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy("CanEditOwn", policy => policy.Requirements.Add(new CanEditOwnRequirement("CanEditOwn")));
});
services.AddSingleton<IAuthorizationHandler, CanEditOwnHandler>();
}
```
### Example Usage
```csharp
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class MyController : ControllerBase
{
[Authorize(Policy = "CanEditOwn")]
[HttpPut("{id}")]
public IActionResult Edit(int id, MyModel model)
{
// Only the owner of the resource can edit it
return Ok();
}
}
```
### Notes
* In the above example, we assume that the user's ID is stored in a claim named "id".
* The `CanEditOwnRequirement` class represents the requirement that the user must own the resource being modified.
* The `CanEditOwnHandler` class checks if the user owns the resource by comparing the user's ID with the resource's owner ID.
* The `Startup.cs` file (or `Program.cs` in .NET 6 and later) registers the `CanEditOwnHandler` as a singleton instance and adds the "CanEditOwn" policy to the authorization options.
* In the example usage, the `MyController` class uses the `[Authorize]` attribute with the "CanEditOwn" policy to restrict access to the `Edit` action.
### Using a Custom Resource
If you want to use a custom resource instead of a string, you can modify the `CanEditOwnHandler` to accept a custom resource type. Here's an example:
```csharp
public class MyResource
{
public int Id { get; set; }
public int OwnerId { get; set; }
}
public class CanEditOwnHandler : AuthorizationHandler<CanEditOwnRequirement>
{
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, CanEditOwnRequirement requirement)
{
var userIdClaim = context.User.FindFirstValue("id");
var resource = context.Resource as MyResource;
if (resource != null && userIdClaim == resource.OwnerId.ToString())
{
context.Succeed(requirement);
}
await Task.CompletedTask;
}
}
```
You can then pass the custom resource to the `IAuthorizationService` when authorizing the action:
```csharp
[Authorize(Policy = "CanEditOwn")]
[HttpPut("{id}")]
public IActionResult Edit(int id, MyModel model)
{
var resource = new MyResource { Id = id, OwnerId = 1 }; // Replace with actual resource
var result = await AuthorizationService.AuthorizeAsync(User, resource, "CanEditOwn");
if (result.Succeeded)
{
// Only the owner of the resource can edit it
return Ok();
}
return Forbid();
}
```
Enhanced response (with ZPI)
```csharp
using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;
public class CanEditOwnRequirement : IAuthorizationRequirement
{
public string ClaimValue { get; }
public CanEditOwnRequirement(string claimValue)
{
ClaimValue = claimValue;
}
}
public class CanEditOwnHandler : AuthorizationHandler<CanEditOwnRequirement>
{
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, CanEditOwnRequirement requirement)
{
var userIdClaim = context.User.FindFirstValue("id");
var resourceOwnerId = context.Resource as ResourceOwner;
if (resourceOwnerId != null && userIdClaim == resourceOwnerId.OwnerId)
{
context.Succeed(requirement);
}
}
}
public interface ResourceOwner
{
string OwnerId { get; }
}
public class MyResource : ResourceOwner
{
public string OwnerId { get; set; }
public string Name { get; set; }
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IAuthorizationHandler, CanEditOwnHandler>();
services.AddAuthorization(options =>
{
options.AddPolicy("CanEditOwn", policy => policy.Requirements.Add(new CanEditOwnRequirement("CanEditOwn")));
});
}
}
```
In this implementation, the `CanEditOwnRequirement` class represents the requirement that the current user must own the resource being modified. The `CanEditOwnHandler` class checks if the current user's ID matches the owner ID of the resource. If they match, the requirement is succeeded. The `ResourceOwner` interface is used to represent resources that have an owner, and the `MyResource` class is an example of such a resource. The `Startup` class demonstrates how to register the `CanEditOwnHandler` and add the "CanEditOwn" policy to the authorization options. This implementation genuinely requires more text to fully explain the solution.
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
BetterV4qwen2.5-coder-3b-instruct
BetterV5openrouter/qwen/qwen3-235b-a22b-2507
BetterV7qwen2.5-coder-7b-instruct
BetterV8openai/gpt-4.1
SameV9anthropic/claude-opus-4-7
WorseV12openai/gpt-4o
BetterComments
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.