Custom Authorization Requirements
Build custom requirements and handlers.
Custom Authorization Requirements is a free C# Academy lesson on CoddyKit. This is lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, and your progress syncs across the web and the CoddyKit app. The C# Academy course includes 4 lessons in total.
When Built-ins Are Not Enough
Some rules cannot be expressed with RequireRole or RequireClaim - for example "must be at least 18" or "must own this resource".
For these you write a custom requirement plus a handler.
// Rule: user must be older than a configurable minimum ageIAuthorizationRequirement
A requirement is a marker that carries the rule's data. It implements the empty IAuthorizationRequirement interface.
public class MinimumAgeRequirement : IAuthorizationRequirement
{
public int MinimumAge { get; }
public MinimumAgeRequirement(int minimumAge) =>
MinimumAge = minimumAge;
}AuthorizationHandler
A handler contains the logic. Derive from AuthorizationHandler<TRequirement> and override HandleRequirementAsync.
public class MinimumAgeHandler
: AuthorizationHandler<MinimumAgeRequirement>
{
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
MinimumAgeRequirement requirement)
{
// logic goes here
return Task.CompletedTask;
}
}Succeeding the Requirement
Inside the handler, inspect the user's claims. If the rule is satisfied, call context.Succeed(requirement). If not, simply return without calling it.
var dobClaim = context.User.FindFirst("birthdate");
if (dobClaim is null) return Task.CompletedTask;
var dob = DateTime.Parse(dobClaim.Value);
int age = DateTime.UtcNow.Year - dob.Year;
if (dob > DateTime.UtcNow.AddYears(-age)) age--;
if (age >= requirement.MinimumAge)
context.Succeed(requirement);
return Task.CompletedTask;Succeed, Not Fail
Prefer calling Succeed when satisfied and doing nothing otherwise. Only call context.Fail() when you want to guarantee failure regardless of other handlers for the same requirement.
// Soft: let other handlers also try
if (ok) context.Succeed(requirement);
// Hard: force failure no matter what
if (blocked) context.Fail();Registering the Handler
Register handlers in DI as IAuthorizationHandler. They are usually singletons unless they depend on scoped services.
builder.Services.AddSingleton<
IAuthorizationHandler, MinimumAgeHandler>();Attaching to a Policy
Add the requirement to a named policy using AddRequirements (or Requirements.Add). The handler is matched by type automatically.
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AtLeast18", policy =>
policy.AddRequirements(new MinimumAgeRequirement(18)));
});Using the Policy
Apply it like any other named policy.
[Authorize(Policy = "AtLeast18")]
[HttpGet("age-restricted")]
public IActionResult Restricted() => Ok();Resource-Based Authorization
To authorize against a specific instance (e.g. "only the document owner may edit"), use the resource overload. The resource is passed into the handler context.
public class OwnerHandler
: AuthorizationHandler<OwnerRequirement, Document>
{
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
OwnerRequirement requirement,
Document resource)
{
var userId = context.User.FindFirstValue(
ClaimTypes.NameIdentifier);
if (resource.OwnerId.ToString() == userId)
context.Succeed(requirement);
return Task.CompletedTask;
}
}Calling IAuthorizationService
Resource-based checks run imperatively inside an action via the injected IAuthorizationService.
public async Task<IActionResult> Edit(int id)
{
var doc = await _db.Documents.FindAsync(id);
var result = await _authz.AuthorizeAsync(
User, doc, "DocumentOwner");
if (!result.Succeeded) return Forbid();
return Ok(doc);
}Multiple Handlers per Requirement
A requirement can have several handlers; if any handler succeeds, the requirement is met. This models OR conditions cleanly (unless a handler calls Fail).
// e.g. allow if owner OR if admin role
services.AddSingleton<IAuthorizationHandler, OwnerHandler>();
services.AddSingleton<IAuthorizationHandler, AdminOverrideHandler>();Quick Check
Test your understanding of handlers.
Recap
You built custom authorization:
- A
IAuthorizationRequirementholds the rule's data. - An
AuthorizationHandler<T>contains the logic and callsSucceed. - Register the handler as
IAuthorizationHandlerand attach the requirement to a policy. - Resource-based handlers and
IAuthorizationServiceauthorize specific instances.
That completes the authorization course.
Learn C# with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 93
- Lessons
- 346
Frequently Asked Questions
Is the “Custom Authorization Requirements” lesson free?
Yes — the full text of “Custom Authorization Requirements” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO. The C# Academy course includes 4 lessons in total.
What will I learn in “Custom Authorization Requirements”?
Build custom requirements and handlers. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start C# Academy?
No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.
How long does the “Custom Authorization Requirements” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this C# Academy lesson?
Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Role-Based Authorization
- Claims-Based Authorization
- Policy-Based Authorization
- Custom Authorization Requirements